ЁЯОп рдзрдбрд╛ 03 тАФ Test design: рдпреЛрдЧреНрдп рдкреНрд░рд╢реНрди 34.5 рд╡рд░рдЪрд╛ bug рд╢реЛрдзрддрд╛рдд
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 03 ┬╖ рдорд╛рдЧреЗ: lesson-02-unit-tests ┬╖ рдкреБрдвреЗ: lesson-04-fixtures
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ02, рдЖрдгрд┐ рдкреНрд░рд╢реНрди рдХрд╕реЗ рдирд┐рд╡рдбрд╛рдпрдЪреЗ: equivalence classes (рдЙрддреНрддрд░рд╛рдЪреНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░рд╛рд╕рд╛рдареА
рдПрдХ рдкреНрд░рд╢реНрди), boundary values (рдиреЗрдордХреЗ рдХрдбрд╛рдВрд╡рд░рдЪреЗ рдкреНрд░рд╢реНрди, рдЬрд┐рдереЗ bugs рд░рд╛рд╣рддрд╛рдд) рдЖрдгрд┐
decision tables (рдирд┐рдпрдорд╛рдВрдЪреНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдЬреЛрдбреАрд╕рд╛рдареА рдПрдХ рдкреНрд░рд╢реНрди). рдпрд╛рдВрдЪреНрдпрд╛ рдорджрддреАрдиреЗ рдХрддрд░рд┐рдирд╛рд▓рд╛
grade_v1 рдЪрд╛ 34.5 рд╡рд░рдЪрд╛ bug рд╕рд╛рдкрдбрддреЛ тАФ рдЖрдгрд┐ рдЖрдгрдЦреА рджреЛрди. exam/demo.py рдордзрд▓реЗ
design().
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдХрддрд░рд┐рдирд╛ рдкреНрд░рддреНрдпреЗрдХ рд╢рдХреНрдп score рдмрджреНрджрд▓ рд╡рд┐рдЪрд╛рд░реВ рд╢рдХрдд рдирд╛рд╣реА. рдореНрд╣рдгреВрди рддреА рдЧрдЯрд╛рдВрдордзреНрдпреЗ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ. ЁЯЧВя╕П
45 рддреЗ 59 рдордзрд▓реНрдпрд╛ рд╕рдЧрд│реНрдпрд╛ scores рдирд╛ C рдорд┐рд│рддреЛ. 50 рдХрд┐рдВрд╡рд╛ 52 рдмрджреНрджрд▓ рд╡рд┐рдЪрд╛рд░рд▓реЗ рддрд░реА рддрд┐рд▓рд╛ рддреЗрдЪ рдХрд│рддреЗ. рдореНрд╣рдгреВрди рд╕реБрд░реБрд╡рд╛рддреАрд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ рдЧрдЯрд╛рддреВрди рдПрдХ рдкреНрд░рд╢реНрди рдкреБрд░реЗрд╕рд╛: рдПрдХ F, рдПрдХ D, рдПрдХ C, рдПрдХ B, рдПрдХ A тАФ рдЖрдгрд┐ рджреЛрди рд╡рд┐рдЪрд┐рддреНрд░ scores, тИТ0.1 рдЖрдгрд┐ 100.1, рдЬреЗ рдирд╛рдХрд╛рд░рд▓реЗ рдЧреЗрд▓реЗрдЪ рдкрд╛рд╣рд┐рдЬреЗрдд.
рд╕рд╛рдд рдкреНрд░рд╢реНрди. рд╕рд╛рддрд╣реА pass. Bug рдЕрдЬреВрдирд╣реА рддрд┐рдереЗрдЪ рдЖрд╣реЗ.
рдордЧ рддреА рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ: "рдЪреБрдХрд╛ рдХреБрдареЗ рд╣реЛрддрд╛рдд? рдЧрдЯрд╛рдВрдордзрд▓реНрдпрд╛ рдХрдбрд╛рдВрд╡рд░." ЁЯЪз рдореНрд╣рдгреВрди рддреА 34.4, 34.5, 34.6 рдЖрдгрд┐ 35 рдмрджреНрджрд▓ рд╡рд┐рдЪрд╛рд░рддреЗ. рдЖрдгрд┐ рддрд╕реЗрдЪ 45, 60 рдЖрдгрд┐ 75 рд╡рд░.
34.5 рд╡рд░ code рдореНрд╣рдгрддреЛ F. рдирд┐рдпрдо рдореНрд╣рдгрддреЛ D. рдкрдХрдбрд▓рд╛. ЁЯОп рдЖрдгрд┐ 44.5 рдЖрдгрд┐ 74.5 рд╡рд░рд╕реБрджреНрдзрд╛.
рд╢реЗрд╡рдЯреА, report card: "average pass рдЕрд╕реЗрд▓ рдЖрдгрд┐ attendance рдХрд┐рдорд╛рди 75% рдЕрд╕реЗрд▓ рддрд░ promoted тАФ рдХрд┐рдВрд╡рд╛ medical note рдЕрд╕реЗрд▓ рддрд░". рддреАрди рд╣реЛ/рдирд╛рд╣реА рдкреНрд░рд╢реНрдирд╛рдВрдЪреНрдпрд╛ 8 рдЬреЛрдбреНрдпрд╛ рд╣реЛрддрд╛рдд. рдХрддрд░рд┐рдирд╛ рд╕рдЧрд│реНрдпрд╛ 8 рдЪрд╛ рдПрдХ рддрдХреНрддрд╛ рдХрд╛рдврддреЗ, рдореНрд╣рдгрдЬреЗ рдХреЛрдгрддреАрд╣реА рдЬреЛрдбреА рд╡рд┐рд╕рд░рд▓реА рдЬрд╛рдд рдирд╛рд╣реА.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
subgraph eq["ЁЯЧВя╕П equivalence classes: 7 questions, 0 bugs"]
e["-0.1 refused ┬╖ 17 F ┬╖ 40 D ┬╖ 52 C ┬╖ 67 B ┬╖ 88 A ┬╖ 100.1 refused"]
end
subgraph bv["ЁЯЪз boundary values: 16 questions, 3 bugs"]
b["34.4 F ┬╖ 34.5 v1 F, rule D тЖР BUG ┬╖ 35 D<br/>44.5 тЖР BUG ┬╖ 59.5 ok by luck ┬╖ 74.5 тЖР BUG"]
end
subgraph dt["ЁЯУЛ decision table: 3 conditions, 8 rules"]
d["average passes? ┬╖ attendance at least 75%? ┬╖ medical note?"]
end
eq --> bv --> dt
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/testing/lesson-diagrams.html#l03
тЭУ рдХрд╛рдп
- Equivalence partitioning (equivalence classes) тАФ inputs рдирд╛ рдЕрд╢рд╛ рдЧрдЯрд╛рдВрдд рд╡рд┐рднрд╛рдЧрд╛ рдЬреНрдпрд╛рдВрдирд╛
code рдиреЗ рд╕рд╛рд░рдЦреЗрдЪ рд╡рд╛рдЧрд╡рд╛рдпрд▓рд╛ рд╣рд╡реЗ, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЧрдЯрд╛рддреВрди рдПрдХ рдХрд┐рдВрдордд test рдХрд░рд╛.
gradeрд╕рд╛рдареА: 0 рдЦрд╛рд▓реА, F, D, C, B, A, 100 рд╡рд░ тАФ рд╕рд╛рдд classes. - Boundary value analysis тАФ bugs classes рдЪреНрдпрд╛ рдХрдбрд╛рдВрд╡рд░ рдЧреЛрд│рд╛ рд╣реЛрддрд╛рдд:
>=рд╡рд┐рд░реБрджреНрдз>, off-by-one, rounding. рдХрдб рд╕реНрд╡рддрдГ рдЖрдгрд┐ рджреЛрдиреНрд╣реА рдмрд╛рдЬреВрдВрдЪреЗ рддрд┐рдЪреЗ рд╕рд░реНрд╡рд╛рдд рдЬрд╡рд│рдЪреЗ рд╢реЗрдЬрд╛рд░реА test рдХрд░рд╛. Round рдХреЗрд▓реЗрд▓реНрдпрд╛ score рд╡рд░рдЪреНрдпрд╛ рдирд┐рдпрдорд╛рд╕рд╛рдареА, рд╢реЗрдЬрд╛рд░реА рдореНрд╣рдгрдЬреЗ рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдЬреВрд▓рд╛ round рд╣реЛрдгрд╛рд▒реНрдпрд╛ рдХрд┐рдорддреА: 34.4 рдЖрдгрд┐ 34.5. - Decision table тАФ рдЕрдЯреАрдВрдЪреА рдкреНрд░рддреНрдпреЗрдХ рдЬреЛрдбреА (рдЗрдереЗ 2 ├Ч 2 ├Ч 2 = 8) рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХреАрдЪрд╛ рдЕрдкреЗрдХреНрд╖рд┐рдд рдирд┐рдХрд╛рд▓ рдпрд╛рдВрдЪреА рдпрд╛рджреА рдХрд░рд╛. рдХреЛрдгреАрдЪ рди рд╕рд╛рдВрдЧрд┐рддрд▓реЗрд▓реНрдпрд╛ рдЬреЛрдбреНрдпрд╛ рддреНрдпрд╛рддреВрди рдЙрдШрдб рд╣реЛрддрд╛рдд.
- Exhaustive testing тАФ рдкреНрд░рддреНрдпреЗрдХ input рд╡рд╛рдкрд░реВрди рдкрд╛рд╣рдгреЗ. рд╕рд╣рд╕рд╛ рдЕрд╢рдХреНрдп (floats, strings), рдкрдг input space рд▓рд╣рд╛рди рдЕрд╕реЗрд▓ рддреЗрд╡реНрд╣рд╛ рд╣реА рд╕рд░реНрд╡рд╛рдд рднрдХреНрдХрдо test рдЕрд╕рддреЗ: demo 0 рддреЗ 100 рдордзрд▓реЗ рд╕рдЧрд│реЗ 201 half-mark scores рддрдкрд╛рд╕рддреЛ.
- Parametrized test тАФ рдПрдХрдЪ test body, (input, expected) рдУрд│реАрдВрдЪрд╛ рдПрдХ рддрдХреНрддрд╛. рдкреНрд░рддреНрдпреЗрдХ рдУрд│ рд╡реЗрдЧрд│реА report рд╣реЛрддреЗ.
- Round-half-to-even тАФ Python рдЪреНрдпрд╛
round()рдЪрд╛ рдирд┐рдпрдо: рдмрд░реЛрдмрд░реА рдЭрд╛рд▓реНрдпрд╛рд╕ рд╕рдо рд╢реЗрдЬрд╛рд▒реНрдпрд╛рдХрдбреЗ. рдореНрд╣рдгреВрдирдЪ 34.5 тЖТ 34 (рдЗрдереЗ рдЪреВрдХ) рдкрдг 59.5 тЖТ 60 (рдпреЛрдЧрд╛рдпреЛрдЧрд╛рдиреЗ рдмрд░реЛрдмрд░).
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг рд╢рдХреНрдп inputs рдЪреА рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рдЪрдВрдб рдЖрд╣реЗ рдЖрдгрд┐ рддреБрдореНрд╣рд╛рд▓рд╛ рдкрд░рд╡рдбрдгрд╛рд▒реНрдпрд╛ tests рдЪреА рд╕рдВрдЦреНрдпрд╛ рд▓рд╣рд╛рди. Test design рдореНрд╣рдгрдЬреЗ рдЪреБрдХреАрдЪреЗ рдЙрддреНрддрд░ рдкрдХрдбрдгреНрдпрд╛рдЪреА рд╕рд░реНрд╡рд╛рдзрд┐рдХ рд╢рдХреНрдпрддрд╛ рдЕрд╕рд▓реЗрд▓реЗ рдереЛрдбреЗ рдкреНрд░рд╢реНрди рдирд┐рд╡рдбрдгреЗ. рд╕рд╛рдд class рдкреНрд░рд╢реНрдирд╛рдВрдЪреА рдХрд┐рдВрдордд рд╕рд╛рдд boundary рдкреНрд░рд╢реНрдирд╛рдВрдЗрддрдХреАрдЪ рдЖрд╣реЗ, рдкрдг bug рдлрдХреНрдд boundary рдкреНрд░рд╢реНрдирд╛рдВрдирд╛рдЪ рд╕рд╛рдкрдбрд▓рд╛.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
exam/demo.py рдордзрд▓реЗ design() рд╕рд╛рдд class рдХрд┐рдорддреА grade рдордзреВрди рдЪрд╛рд▓рд╡рддреЗ,
рдордЧ рджрд╣рд╛ boundary рдХрд┐рдорддреА grade_v1 рдЖрдгрд┐ grade рджреЛрдиреНрд╣реАрдВрдордзреВрди рдЪрд╛рд▓рд╡реВрди рдкреНрд░рддреНрдпреЗрдХ рдлрд░рдХ рдЦреБрдгрд╛рд╡рддреЗ,
рдордЧ 0 рддреЗ 100 рдордзрд▓реЗ рд╕рдЧрд│реЗ 201 half marks. Decision table exam/grades.py
рдордзрд▓реЗ report_card() average (70 рдХрд┐рдВрд╡рд╛ 30), attendance (90% рдХрд┐рдВрд╡рд╛ 60%) рдЖрдгрд┐ medical note
(рд╣реЛ рдХрд┐рдВрд╡рд╛ рдирд╛рд╣реА) рдпрд╛рдВрдЪреНрдпрд╛ 8 рдкреИрдХреА рдкреНрд░рддреНрдпреЗрдХ рдЬреЛрдбреАрд╕рд╛рдареА рдмреЛрд▓рд╡рддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 exam/demo.py design
python3 - <<'EOF'
from exam.grades import grade, grade_v1
classes = {"invalid low": -0.1, "F": 17, "D": 40, "C": 52, "B": 67, "A": 88, "invalid high": 100.1}
for name, s in classes.items():
try: print(f"{name:<12} {s:>5} тЖТ v1 {grade_v1(s)} ┬╖ fixed {grade(s)}")
except ValueError: print(f"{name:<12} {s:>5} тЖТ refused")
edges = []
for cut in (35, 45, 60, 75):
edges += [cut - 0.6, cut - 0.5, cut - 0.4, cut]
found = [s for s in edges if grade_v1(s) != grade(s)]
print(f"{len(edges)} boundary questions, v1 wrong at {[round(s, 1) for s in found]}")
print("the classes alone found:", [n for n, s in classes.items() if s >= 0 and s <= 100 and grade_v1(s) != grade(s)])
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
design рдЫрд╛рдкрддреЗ (рдХрд╛рд╣реА рднрд╛рдЧ):
34.4: v1 F ┬╖ fixed F
34.5: v1 F ┬╖ fixed D тЖР BUG
35: v1 D ┬╖ fixed D
44.5: v1 D ┬╖ fixed C тЖР BUG
59.5: v1 B ┬╖ fixed B
74.5: v1 B ┬╖ fixed A тЖР BUG
every half-mark 0тАУ100 (201 scores): v1 is wrong at [34.5, 44.5, 74.5] тАФ round() sends halves to the EVEN number
average 70 ┬╖ attendance 60% ┬╖ note yes тЖТ promoted
average 30 ┬╖ attendance 90% ┬╖ note yes тЖТ held back
рддреБрдордЪрд╛ snippet рдЫрд╛рдкрддреЛ:
invalid low -0.1 тЖТ refused
F 17 тЖТ v1 F ┬╖ fixed F
D 40 тЖТ v1 D ┬╖ fixed D
C 52 тЖТ v1 C ┬╖ fixed C
B 67 тЖТ v1 B ┬╖ fixed B
A 88 тЖТ v1 A ┬╖ fixed A
invalid high 100.1 тЖТ refused
16 boundary questions, v1 wrong at [34.5, 44.5, 74.5]
the classes alone found: []
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рд╕рд╛рдд рдиреАрдЯ рдирд┐рд╡рдбрд▓реЗрд▓реНрдпрд╛ class рдкреНрд░рд╢реНрдирд╛рдВрдирд╛ рдХрд╛рд╣реАрдЪ рд╕рд╛рдкрдбрд▓реЗ рдирд╛рд╣реА; рд╕реЛрд│рд╛ boundary рдкреНрд░рд╢реНрдирд╛рдВрдирд╛
рддрд┐рдиреНрд╣реА рдЪреБрдХреАрдЪреЗ scores рд╕рд╛рдкрдбрд▓реЗ. Classes рддрд░реАрд╣реА рдЙрдкрдпреЛрдЧреА рдЖрд╣реЗрдд тАФ рдкреНрд░рддреНрдпреЗрдХ grade рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪрддрд╛ рдпреЗрддреЗ рдЖрдгрд┐
рд╡рд┐рдЪрд┐рддреНрд░ scores рдирд╛рдХрд╛рд░рд▓реЗ рдЬрд╛рддрд╛рдд рд╣реЗ рддреНрдпрд╛ рд╕рд┐рджреНрдз рдХрд░рддрд╛рдд тАФ рдкрдг bugs рдХрдбрд╛рдВрд╡рд░ рд╣реЛрддреЗ. Decision
table рдЕрд╕рд╛ рдирд┐рдпрдо рджрд╛рдЦрд╡рддреЗ рдЬреЛ рд╡рд╛рдЪрдгрд╛рд▒реНрдпрд╛рдЪреНрдпрд╛ рдирдЬрд░реЗрддреВрди рд╕реБрдЯреВ рд╢рдХрддреЛ: medical note рдХрдореА attendance рд▓рд╛ рд╡рд╛рдЪрд╡рддреЗ, рдкрдг
fail рд╣реЛрдгрд╛рд▒реНрдпрд╛ average рд▓рд╛ рдХрдзреАрдЪ рдирд╛рд╣реА (average 30 ┬╖ note yes тЖТ held back).
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- рдкреНрд░рддреНрдпреЗрдХ class рдЪрд╛ рдордзрд▓рд╛ рднрд╛рдЧ test рдХрд░рдгреЗ рдЖрдгрд┐ рдХрдб рдХрдзреАрдЪ рдирд╛рд╣реА
- рдХрдб рдлрдХреНрдд рдПрдХрд╛рдЪ рдмрд╛рдЬреВрдиреЗ test рдХрд░рдгреЗ (35 рдкрдг 34.5 рдирд╛рд╣реА)
- рдЕрд╡реИрдз classes рд╡рд┐рд╕рд░рдгреЗ: negative, рдЦреВрдк рдореЛрдареЗ, рд░рд┐рдХрд╛рдореЗ, рдЪреБрдХреАрдЪрд╛ type
- рдирд┐рдпрдорд╛рдЪреНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдУрд│реАрд╕рд╛рдареА рдПрдХ test рдРрд╡рдЬреА code рдордзрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ
ifрд╕рд╛рдареА рдПрдХ test тАФ code рдордзреНрдпреЗ рдПрдЦрд╛рджреА рдУрд│рдЪ рдирд╕реВ рд╢рдХрддреЗ - code рдордзрд▓реНрдпрд╛ boundaries test рдордзреНрдпреЗ copy рдХрд░рдгреЗ, рдореНрд╣рдгрдЬреЗ рдЪреБрдХреАрдЪреА boundary рд╕реНрд╡рддрдГрд╢реАрдЪ рддрдкрд╛рд╕рд▓реА рдЬрд╛рддреЗ
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ project рд╡рд░ тАФ boundary рддрдХреНрддрд╛ рдПрдХрд╛рдЪ parametrized pytest test рдордзреНрдпреЗ; рдкреНрд░рддреНрдпреЗрдХ рдУрд│ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ line рд╡рд░ report рд╣реЛрддреЗ:
import pytest
from exam.grades import grade
@pytest.mark.parametrize("score, expected", [
(34.4, "F"), (34.5, "D"), (35, "D"),
(44.4, "D"), (44.5, "C"), (45, "C"),
(59.4, "C"), (59.5, "B"), (60, "B"),
(74.4, "B"), (74.5, "A"), (75, "A"),
])
def test_grade_boundaries(score, expected):
assert grade(score) == expected
unittest рдордзреНрдпреЗ рд╣реАрдЪ рдХрд▓реНрдкрдирд╛ subTest рд╡рд╛рдкрд░рддреЗ, рдореНрд╣рдгрдЬреЗ рдПрдХ failing рдУрд│ рдмрд╛рдХреАрдЪреНрдпрд╛рдВрдирд╛ рд▓рдкрд╡рдд рдирд╛рд╣реА:
def test_boundaries(self):
for score, expected in [(34.5, "D"), (44.5, "C"), (74.5, "A")]:
with self.subTest(score=score):
self.assertEqual(grade(score), expected)
рд╣реА рддрдВрддреНрд░реЗ ISTQB tester syllabus рдордзреНрдпреЗ standard рдЖрд╣реЗрдд (equivalence partitioning, boundary value analysis, decision table testing, state transition testing) рдЖрдгрд┐ рдХреЛрдгрддреНрдпрд╛рд╣реА рднрд╛рд╖реЗрдд рд▓рд╛рдЧреВ рд╣реЛрддрд╛рдд.
ЁЯПн Production рдордзреНрдпреЗ рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: рдЬреНрдпрд╛ рдирд┐рдпрдорд╛рдд рдПрдЦрд╛рджрд╛ рдЖрдХрдбрд╛ рдЖрд╣реЗ тАФ pass mark, price threshold, rate limit, date cut-off тАФ рддреНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХрд╛рд╕рд╛рдареА рдЖрдзреА boundary рддрдХреНрддрд╛ рд▓рд┐рд╣рд╛. Users рдиреА report рдХреЗрд▓реЗрд▓реЗ рдмрд╣реБрддреЗрдХ "рдЕрд╢рдХреНрдп" bugs рдиреЗрдордХреЗ рдПрдЦрд╛рджреНрдпрд╛ рдХрдбреЗрд╡рд░ рдмрд╕рд▓реЗрд▓реЗ рдЕрд╕рддрд╛рдд.
тПня╕П рдкреБрдвреЗ
рдЪрд╛рдВрдЧрд▓реНрдпрд╛ рдкреНрд░рд╢реНрдирд╛рдВрдирд╛ рдЪрд╛рдВрдЧрд▓реНрдпрд╛ рдЙрддреНрддрд░рдкрддреНрд░рд┐рдХрд╛ рд▓рд╛рдЧрддрд╛рдд: test data. рдкреНрд░рддреНрдпреЗрдХ test рдордзреНрдпреЗ рддреНрдпрд╛ рд╣рд╛рддрд╛рдиреЗ рдмрдирд╡рдгреЗ рд╣рд│реВ рдЖрдгрд┐ рдирд╛рдЬреВрдХ рдЖрд╣реЗ. Builders, setup рдЖрдгрд┐ teardown, рдЖрдгрд┐ рдПрдХрдореЗрдХрд╛рдВрд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдирд╕рд▓реЗрд▓реЗ tests.
git checkout lesson-04-fixtures