Tips for Better Suggestions
Tests, Documentation, and Code Review with Copilot
Beyond writing application code, Copilot is excellent at the supporting work that engineers often procrastinate: writing tests, documentation, and reviewing code. This lesson focuses on these high-leverage uses.
Generating tests
Tests are one of the best use cases for Copilot because:
- They follow predictable patterns
- The model has seen millions of test files
- A test is essentially a specification — giving it to Copilot is natural
Using /tests in Chat
Select a function, open Chat, type /tests. Copilot generates a test file or test cases. Make your request specific:
code/tests Generate pytest unit tests for this function covering: 1. Normal case with valid inputs 2. Empty list input 3. Negative numbers in the input 4. All elements the same value 5. List with a single element Use fixtures for repeated setup. Assert specific values, not just that no exception is raised.
The more specific the list of cases, the better. If you just say /tests, you get a generic set. If you specify the edge cases, you get the tests you actually need.
Test-driven development with Copilot
Write the test first, then let Copilot implement the function. This is powerful because the test is precise and executable — it is a better specification than a comment.
pythondef test_parse_duration(): assert parse_duration("1h30m") == 5400 # seconds assert parse_duration("45s") == 45 assert parse_duration("2h") == 7200 assert parse_duration("0s") == 0 assert parse_duration("invalid") is None
Now type
def parse_duration(s: str) -> int | None:Generating documentation
Documentation is another area where Copilot saves significant time.
Docstrings with /doc
Select a function, open Chat, type /doc. Copilot generates a docstring in the appropriate format for the language (JSDoc for JS/TS, Google-style or NumPy-style for Python, etc.).
Specify the format if needed:
code/doc Generate a Google-style docstring for this function. Include: brief description, Args section with types and descriptions, Returns section, Raises section for exceptions that can be thrown, and an Example section with one usage example.
README and module documentation
For a whole module:
code#file:src/services/paymentService.ts Generate a README section for this module. Include: what it does, the main functions with brief descriptions, error handling behavior, and example usage.
Inline comments for complex logic
For genuinely complex code (not trivial code — avoid commenting obvious things):
codeAdd a concise inline comment before each non-obvious step in this function. Explain the "why", not the "what". Do not add comments to self-explanatory lines.
Using Copilot for code review
Review a selection
Select a function or file, open Chat, and ask:
codeReview this code for: 1. Potential bugs or edge cases not handled 2. Security issues (injection, auth bypass, data exposure) 3. Performance problems 4. Clarity and maintainability issues Be specific about line numbers or variable names when pointing out issues.
Understand a diff
On GitHub.com, select code in a pull request diff and ask Copilot to explain it. Useful when reviewing a language or framework you are less familiar with.
Generate review comments
code#file:services/orderService.ts Generate three to five substantive code review comments for this file. Focus on correctness, error handling, and adherence to the repository patterns. Format each as: [severity: minor/major/critical] Description. Suggested fix.
You edit these into your actual review.
Refactoring with Copilot Chat
Refactoring is where Chat shines. Select the code you want to refactor and describe exactly what you want:
codeRefactor this function: 1. Extract the three database calls into separate private functions 2. Replace the nested if-else with early returns 3. Add error handling for database failures that currently propagate uncaught 4. Keep the public interface identical — same function name, same parameters, same return type
The constraints in point 4 are critical. Without "same interface", Copilot might rename things or change signatures, breaking callers.