Browse Source

CLDC-NONE: Add documentation on structuring test suites

CLDC-NONE-document-best-practices-for-time-travel
samyou-softwire 6 days ago
parent
commit
2c139a075f
  1. 46
      docs/testing/best_practice.md

46
docs/testing/best_practice.md

@ -30,3 +30,49 @@ If you're currently in new form build and writing new tests, imagine that it is
- If writing a test for the present & future, use `collection_start_date_for_year_or_later(year)`, and mark the test with metadata: `{ year: xx }`. - If writing a test for the present & future, use `collection_start_date_for_year_or_later(year)`, and mark the test with metadata: `{ year: xx }`.
We only maintain tests for years that are currently editable in CORE (usually this and last collection year). If you see a file that contains tests for years older, consider updating or removing them. We only maintain tests for years that are currently editable in CORE (usually this and last collection year). If you see a file that contains tests for years older, consider updating or removing them.
## let syntax
You will see many tests using the `let` syntax. For instance `let(:collection_year) { 2026 }`. These are used to define variables specific to a given test. When the variable `collection_year` is called for the first time, the code inside the block will be evaluated.
They are useful for test specific logic. You can define a `before` block in an outer context, and use `let` blocks in an inner context to define the variables used in that before block. This allows for all arrange logic to be written once, drawing from variables defined later in a more specific context.
`let` blocks will not be evaluated till then run in a test. If you need them to be evaluated immediately (say, an inner context uses time travel), define a `let!` block.
## context
Contexts group related tests. They can also define `before` blocks that run before all tests in the context, and set up specific variables using `let`. With proper setup, a series of contexts can do all the arranging tests will need. This means the final test `it` blocks only need to act and assert.
## Example
A test suite may look like
```ruby
describe "class" do
let(:dependent_object) { dependent_object(name: "test", year:) }
context "#method" do
before do
# do some setup with dependent_object and year
end
context "in 2025", metadata: { year: 25 } do
let(:year) { 2025 }
it "works" do
# act
# assert
end
end
context "in 2026 and later", metadata: { year: 26 } do
let(:year) { collection_start_year_for_year_or_later(2026) }
it "works also" do
# act
# assert
end
end
end
end
```

Loading…
Cancel
Save