Extract dev standards from test code examples
Problemβ
The actual prompt to generate test is too long. How to extract dev standards from code example to not repeat the examples in each prompt ?
Control pointsβ
- The prompt should be as efficient as the previous one to generate the tests
Short Answerβ
It works. It could be use to store the standards of the project on the user's side to use it later for future test generation.
Strategy/Solutionβ
By simply asking the AI to generate the dev standards. For this we can use this learning: How to improve the prompt.
Limitationsβ
- The test generation is not better (but not worse) by extracting dev standards first
- The standards can also be very long (see example). So it doesn't save that much tokens. (3000 chars of standards vs 5000 chars)
Exampleβ
We used this prompt and this Pre-prompt:
prompt = f"""
Extract an exhaustive list of dev standards from the following examples of good tests. You may describe :
- which functions to use
- how to import and use them
- what order to use them in
- what to name the variables
- general rules of thumb and best practices
- what to mock and how to mock it
You may include some minimal code examples to illustrate your points. Point out what makes these examples specific to this project.
`
${examples_of_tests}
`
"""
# ... pre-prompt:
{
"role": "system",
"content": "You are a helpful developer who wants to help your team write better tests. You are going to help define a list of good standards that all developers on the project should follow.",
},
# ...
Here is a response :
Based on the provided test cases, these are good standards all developers should
follow:
- **Testing Library:** Developers should use "@testing-library/react-native"
library for writing tests. Use the 'renderWithProviders' function specifically
to render components with the right context.
- **Testing Order:** Individual tests ('it' blocks) should compartmentalize
specific behaviors or interactions to be tested. This keeps tests focused and
easy to reason about. Before anything else the mock data used in the tests
should be defined.
- **Mocks:** Developers should create mock data and functions for testing.
Examples in the code include 'mockGetUser', 'mockLogout' and
'mockGetCityPredictions'. Mocking is a crucial part of testing to avoid
touching real data. Mocks should reside in their respective directory.
- **Assert using Screen:** Using 'screen' to query for elements within the
rendered component is a must. This works like a virtual 'screen' that provides
multiple querying functions.
- **Fire events:** For testing user interactions such as button clicks, use
fireEvent from "@testing-library/react-native".
- **Assertions:** Make assertions using 'expect'. Verify properties, presence or
absence of HTML elements in the components using 'toBeXXX' or 'toHaveXXX'
matchers.
- **Snapshot Tests:** As part of your testing regime, you should have a test
which checks if your component matches previous snapshots
('toMatchComponentSnapshot').
- **Async Testing:** In cases where the execution of tests might depend on
asynchronous code, wrap relevant parts of the test in 'waitFor' or use the
'async/await' pattern to ensure they complete before making assertions.
- **Navigation Testing:** When testing components with navigation actions
involved, use 'getNavigationMock' to simulate the navigation. After firing the
event, make an assertion that the correct navigation function has been called
with correct parameters.
- **Consistent Naming:** Test block names ('describe' and 'it') should
succinctly and accurately describe what is being tested. Names of variables
and mocks should be clear and undertandable to someone reading the code.
Fixture mock names should be prefixed with 'get', and function mocks should be
prefixed with 'mock'.
- **Code Organization:** Tests for a component should be located in the same
source directory as the component itself, and the file name should follow the
format 'Component.test.tsx'.
Minimal code example:
```tsx
import { renderWithProviders } from "#testing/renderWithProviders";
import { fireEvent, screen, waitFor } from "@testing-library/react-native";
describe("MyComponent", () => {
it("displays a title", () => {
renderWithProviders(<MyComponent />);
expect(screen.getByText("MyComponent Title")).toBeOnTheScreen();
});
it("fires a callback when button is pressed", () => {
const mockCallback = jest.fn();
renderWithProviders(<MyComponent onButtonPress={mockCallback} />);
fireEvent.press(screen.getByRole("button", { name: "Button" }));
expect(mockCallback).toHaveBeenCalled();
});
});
```