mirror of
https://github.com/Aider-AI/aider.git
synced 2025-05-23 13:54:59 +00:00
173 lines
7.1 KiB
Markdown
173 lines
7.1 KiB
Markdown
|
|
# Create a "black box" test case
|
|
|
|
This transcript shows GPT-4 creating a black box test case,
|
|
**without being given
|
|
access to the source code of the function being tested or any of the
|
|
other code in the repo.**
|
|
|
|
Instead, GPT is operating entirely off a
|
|
[high level map of the repository based on ctags](https://aider.chat/docs/ctags.html),
|
|
which provides details on all the symbols and function signatures in the repo.
|
|
Using only the meta-data in the map, GPT is able to figure out how to call the method to be tested, as well as how to instantiate multiple class objects that are required to prepare for the test.
|
|
|
|
In detail, GPT is able to use the repo map to:
|
|
|
|
- Find the function signature of the `cmd_add()` function which the user wants a test case for.
|
|
- Determine that it is a method of the `Command` class, so the test case will need to instantiate an instance to conduct the test.
|
|
- Identify that creating a `Command` instance requires passing in `InputOutput` and `Coder` instances.
|
|
- Figure out the arguments required to instantiate the `InputOutput` instance.
|
|
- Decide that the `Coder` class looks complex enough to use a `MagickMock`.
|
|
|
|
The `cmd_add()` method is defined without type annotations, so GPT makes a
|
|
reasonable but incorrect guess that it accepts a `list` of files. The
|
|
user invokes the `/run` command to run the new unit test, which throws an
|
|
error based on this misunderstanding.
|
|
|
|
GPT reviews the error message and fixes the call to `cmd_add()` to
|
|
correctly pass a `str` with a space-separated list of filenames
|
|
instead. The test then passes on the next `/run`.
|
|
|
|
<div class="chat-transcript" markdown="1">
|
|
|
|
> $ aider tests/test_commands.py
|
|
> Creating empty file tests/test_commands.py
|
|
> Added tests/test_commands.py to the chat
|
|
> Files not tracked in .git:
|
|
> - tests/test_commands.py
|
|
>
|
|
> Add them? y
|
|
> Added tests/test_commands.py to the git repo
|
|
> Commit b9cea2c Added new files to the git repo: tests/test_commands.py
|
|
> Using git repo: .git
|
|
|
|
#### add a test for cmd_add that passes in 'foo.txt' and 'bar.txt' and ensures they have both been created after the test. run the test in a tmp dir.
|
|
|
|
I will add a new test method called `test_cmd_add` in the `tests/test_commands.py` file. This test will create a temporary directory, change the current working directory to the temporary directory, and then call the `cmd_add` method with 'foo.txt' and 'bar.txt' as arguments. After that, it will check if both files have been created in the temporary directory.
|
|
|
|
Here's the code change:
|
|
|
|
```python
|
|
tests/test_commands.py
|
|
<<<<<<< ORIGINAL
|
|
=======
|
|
import os
|
|
import tempfile
|
|
from unittest import TestCase
|
|
from unittest.mock import MagicMock
|
|
from aider.commands import Commands
|
|
from aider.io import InputOutput
|
|
|
|
class TestCommands(TestCase):
|
|
def test_cmd_add(self):
|
|
# Create a temporary directory and change the current working directory
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
os.chdir(tmpdir)
|
|
|
|
# Initialize the Commands and InputOutput objects
|
|
io = InputOutput(pretty=False, yes=True)
|
|
coder = MagicMock()
|
|
commands = Commands(io, coder)
|
|
|
|
# Call the cmd_add method with 'foo.txt' and 'bar.txt'
|
|
commands.cmd_add(["foo.txt", "bar.txt"])
|
|
|
|
# Check if both files have been created in the temporary directory
|
|
self.assertTrue(os.path.exists("foo.txt"))
|
|
self.assertTrue(os.path.exists("bar.txt"))
|
|
>>>>>>> UPDATED
|
|
```
|
|
|
|
This test will ensure that the `cmd_add` method creates the specified files in the current working directory.
|
|
|
|
> Applied edit to tests/test_commands.py
|
|
> Commit e2d5212 aider: Added a test method `test_cmd_add` that creates a temporary directory, calls the `cmd_add` method with 'foo.txt' and 'bar.txt', and checks if both files have been created in the temporary directory.
|
|
|
|
#### /run pytest tests/test_commands.py
|
|
|
|
> ```
|
|
> ============================= test session starts ==============================
|
|
> platform darwin -- Python 3.11.3, pytest-7.3.1, pluggy-1.0.0
|
|
> rootdir: /Users/gauthier/Projects/aider
|
|
> collected 1 item
|
|
>
|
|
> tests/test_commands.py F [100%]
|
|
>
|
|
> =================================== FAILURES ===================================
|
|
> __________________________ TestCommands.test_cmd_add ___________________________
|
|
>
|
|
> self = <tests.test_commands.TestCommands testMethod=test_cmd_add>
|
|
>
|
|
> def test_cmd_add(self):
|
|
> # Create a temporary directory and change the current working directory
|
|
> with tempfile.TemporaryDirectory() as tmpdir:
|
|
> os.chdir(tmpdir)
|
|
>
|
|
> # Initialize the Commands and InputOutput objects
|
|
> io = InputOutput(pretty=False, yes=True)
|
|
> coder = MagicMock()
|
|
> commands = Commands(io, coder)
|
|
>
|
|
> # Call the cmd_add method with 'foo.txt' and 'bar.txt'
|
|
> > commands.cmd_add(["foo.txt", "bar.txt"])
|
|
>
|
|
> /Users/gauthier/Projects/aider/tests/test_commands.py:20:
|
|
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
>
|
|
> self = <aider.commands.Commands object at 0x10b412b50>
|
|
> args = ['foo.txt', 'bar.txt']
|
|
>
|
|
> def cmd_add(self, args):
|
|
> "Add matching files to the chat session"
|
|
>
|
|
> added_fnames = []
|
|
> files = self.coder.get_all_relative_files()
|
|
> > for word in args.split():
|
|
> E AttributeError: 'list' object has no attribute 'split'
|
|
>
|
|
> /Users/gauthier/Projects/aider/aider/commands.py:161: AttributeError
|
|
> =========================== short test summary info ============================
|
|
> FAILED tests/test_commands.py::TestCommands::test_cmd_add - AttributeError: '...
|
|
> ============================== 1 failed in 0.34s ===============================
|
|
> ```
|
|
>
|
|
> Add the output to the chat? [y/n] (y): y
|
|
|
|
It seems that the `cmd_add` method in `aider/commands.py` is expecting a string as input, but in the test, we are passing a list. I will update the test to pass a string instead of a list.
|
|
|
|
Here's the code change:
|
|
|
|
```python
|
|
tests/test_commands.py
|
|
<<<<<<< ORIGINAL
|
|
# Call the cmd_add method with 'foo.txt' and 'bar.txt'
|
|
commands.cmd_add(["foo.txt", "bar.txt"])
|
|
=======
|
|
# Call the cmd_add method with 'foo.txt' and 'bar.txt' as a single string
|
|
commands.cmd_add("foo.txt bar.txt")
|
|
>>>>>>> UPDATED
|
|
```
|
|
|
|
Now, run the test again with the updated test method:
|
|
|
|
```
|
|
pytest tests/test_commands.py
|
|
```
|
|
|
|
> Applied edit to tests/test_commands.py
|
|
> Commit d1551b4 aider: Updated test to pass a string instead of a list when calling `cmd_add` method.
|
|
|
|
#### /run pytest tests/test_commands.py
|
|
|
|
> ```
|
|
> ============================= test session starts ==============================
|
|
> platform darwin -- Python 3.11.3, pytest-7.3.1, pluggy-1.0.0
|
|
> rootdir: /Users/gauthier/Projects/aider
|
|
> collected 1 item
|
|
>
|
|
> tests/test_commands.py . [100%]
|
|
>
|
|
> ============================== 1 passed in 0.38s ===============================
|
|
> ```
|
|
|
|
</div>
|