Frameworki kodowe
Testowanie scenariuszami
Zbuduj element, uruchom akcje i sprawdź każdą wartość i zapis.
Co zawiera scenariusz
Scenariusz to plik JSON w scenarios/. Buduje element z danych wejściowych, uruchamia akcje po kolei i sprawdza wyniki. Manifest wymienia każdy plik scenariusza, a każdy plik zawiera jeden scenariusz.
{
"id": "heal-after-damage",
"framework": "keeper",
"parameters": { "name": "Mira", "max_hp": 10 },
"expectedValues": { "name": "Mira", "max_hp": 10, "hp": 10 },
"actions": [
{
"action": "hurt",
"parameters": { "amount": 6 },
"expectedWrites": [{ "op": "ledger.add", "key": "hp", "value": -6 }]
},
{
"action": "heal",
"parameters": { "amount": 9 },
"expectedWrites": [{ "op": "ledger.set", "key": "hp", "value": 10 }]
},
{ "action": "heal", "parameters": { "amount": 3 }, "expectedWrites": [] }
]
}- Wiersze 4-5 Zbuduj element z tych danych wejściowych i sprawdź jego wartości początkowe.
- Wiersz 6 actions wymienia kroki do uruchomienia, po kolei.
- Wiersz 10 Dokładne zapisy, które krok musi wykonać.
- Wiersz 17 Brak zapisów: nic się nie zmieniło.
| Pole | Znaczenie |
|---|---|
| id | Nazwa scenariusza. |
| framework | Id frameworka do zbudowania. |
| parameters | Dane wejściowe, z którymi ma być zbudowany. |
| expectedValues | Każda zapisana wartość tuż po zbudowaniu. |
| expectedChildren | Wartości każdego miejsca podrzędnego. |
| actions | Kroki do uruchomienia, najwyżej 32 na scenariusz. Każdy ma akcję, jej parametry i expectedWrites. |
| ledger | Sprawdzenia wartości pochodnych. |
| lists | Wypełnia listę wpisami, według id presetu. |
| expectedLists | Wpisy, które każda lista zawiera na końcu, według id presetu. |
| poolRolls | Zapisane rzuty dla puli używającej metody roll, według identyfikatora puli. Zobacz Rzucane wyniki. |
| content | Wpisy treści przypięte do zbudowanego Elementu (kind, entryId, name i parameters), scalane z wydaniem tak jak przypięcia postaci. |
Krok może używać dodatkowych pól:
| Pole kroku | Znaczenie |
|---|---|
| choose | Dla akcji listy: wpis, który gracz wybiera dla każdych danych wejściowych ContentRef, według id presetu. |
| expectedRefusal | Odmowa, którą krok musi zakończyć. Taki krok nie oczekuje wtedy żadnych zapisów. |
| expectedValuesAfter | Zapisane i pochodne wartości po kroku. Wartości pochodne są najpierw przeliczane. |
Zapisy
expectedWrites wymienia po kolei każdy zapis wykonany w kroku. Użyj ledger.set dla ustawionej wartości i ledger.add dla dodanej ilości. Krok, który nic nie zmienia, nie wymienia zapisów, więc testowany jest też warunek pomijający zapis.
Jeśli prawdziwe zapisy się różnią, sprawdzenie pokazuje obie listy.
"expectedWrites": [{ "op": "ledger.set", "key": "hp", "value": 9 }]Expected ordered writes [{"op":"ledger.set","key":"hp","value":9}]; observed [{"op":"ledger.set","key":"hp","value":10}].Wartości pochodne i elementy podrzędne
Lista ledger sprawdza funkcję ledgera. Podaje id funkcji, wartość wyjściową i wartość, którą funkcja ma zwrócić. expectedChildren sprawdza elementy podrzędne.
"expectedChildren": { "lamp": { "name": "Lantern", "oil": 5 } },- Wiersz 17 Sprawdza elementy w miejscach podrzędnych.
"ledger": [{ "function": "guard", "currentValue": 0, "expected": 3 }]- Wiersz 18 Wywołuje funkcję warunku z bieżącą wartością 0 i oczekuje 3.
Co trzeba pokryć
- Każdy konstruktor, akcja i funkcja ledgera potrzebuje scenariusza.
- Każda akcja potrzebuje co najmniej jednego kroku. Dodaj krok dla każdej gałęzi, którą chcesz sprawdzić, na przykład jeden, który zapisuje, i jeden, który nic nie zapisuje.
- Akcja, która dodaje do listy, potrzebuje jednego kroku przyjętego i jednego kroku z expectedRefusal, cokolwiek mówi jej oferta. Krok odrzucony dowodzi, że oferta potrafi odmówić. Akcja, która tylko usuwa z listy, potrzebuje jednego kroku przyjętego.
- Oczekiwane wartości muszą odpowiadać temu, co konstruktor naprawdę zwraca, z już zastosowanymi funkcjami ledgera.
Kroki noszą nazwę swojego scenariusza. Komunikat taki jak heal-after-damage-2 oznacza trzeci krok scenariusza heal-after-damage, bo ten numer liczy od 0. Inne komunikaty liczą kroki od 1.
Krok, który oczekuje odmowy od akcji, która nie została odrzucona, kończy się błędem. Tak samo kończy się odwrotny przypadek:
the step expects it to be refused with NOT_OFFEREDAdd expectedRefusalAkcja bez kroku kończy się błędem:
SELF_SCALAR_ACTION_SCENARIO_COVERAGE_MISSING: action keeper.hurt (Take damage) has no executable scenario steps.Akcja listy, której brakuje kroku przyjętego lub odrzuconego, kończy się błędem:
add a step with expectedRefusal, so its refused branch is proven.add a step whose list.add is accepted, so its accepted branch is proven.Oczekiwane wartości różne od tych z konstruktora kończą się błędem:
Constructor output does not match its scenario.Odmowy
Akcja listy może zostać odrzucona. Krok, który tego oczekuje, podaje kod w expectedRefusal i nie wymienia żadnych zapisów.
| Kod | Kiedy |
|---|---|
| NOT_OFFERED | Wybranego wpisu nie ma wśród wpisów, które dopuszcza oferta. |
| ALREADY_IN_LIST | Lista ma już ten wpis. |
| LIST_FULL | Lista osiągnęła maksymalny rozmiar. |
| NOT_IN_LIST | list.remove wskazuje wpis, którego lista nie zawiera. |
| LIST_CAP | Zostałby przekroczony limit zadeklarowany przez listę. |
| SAME_NAME | Lista ma już wpis o tej nazwie. |
Ten projekt potwierdza kilka z nich. Ma też krok, w którym warunek zatrzymuje akcję, więc krok nie oczekuje ani zapisów, ani odmowy.
{
"id": "pack-trinkets",
"framework": "keeper",
"parameters": { "name": "Mira", "max_hp": 10 },
"expectedValues": { "name": "Mira", "max_hp": 10, "hp": 10 },
"actions": [
{
"action": "pack_trinket",
"parameters": {},
"choose": { "trinket": "rope" },
"expectedWrites": [{ "op": "list.add", "key": "pack", "value": "rope" }]
},
{
"action": "pack_trinket",
"parameters": {},
"choose": { "trinket": "rope" },
"expectedRefusal": "ALREADY_IN_LIST",
"expectedWrites": []
},
{
"action": "pack_trinket",
"parameters": {},
"choose": { "trinket": "anvil" },
"expectedRefusal": "NOT_OFFERED",
"expectedWrites": []
},
{
"action": "pack_trinket",
"parameters": {},
"choose": { "trinket": "candle" },
"expectedWrites": [
{ "op": "list.add", "key": "pack", "value": "candle" }
]
},
{
"action": "pack_trinket",
"parameters": {},
"choose": { "trinket": "bell" },
"expectedWrites": []
},
{
"action": "unpack_trinket",
"parameters": {},
"choose": { "trinket": "rope" },
"expectedWrites": [
{ "op": "list.remove", "key": "pack", "value": "rope" }
]
},
{
"action": "unpack_trinket",
"parameters": {},
"choose": { "trinket": "rope" },
"expectedRefusal": "NOT_IN_LIST",
"expectedWrites": []
}
],
"expectedLists": { "pack": ["candle"] }
}- Wiersze 7-12 Przyjęty: list.add zapisuje linę.
- Wiersze 13-19 Odrzucony: lista ma już linę.
- Wiersze 20-26 Odrzucony: oferta nie dopuszcza kowadła.
- Wiersze 35-40 Plecak ma już dwa wpisy, więc warunek nic nie zapisuje i nie oczekujemy odmowy.
- Wiersze 41-48 Usunięty: lina znika z listy.
- Wiersze 49-55 Odrzucony: liny nie ma już na liście.
- Wiersz 57 Plecak kończy ze świecą jako jedynym wpisem.
Uruchamianie
Sprawdź i wyświetl w The Forge kompiluje projekt i uruchamia każdy scenariusz. Nic nie jest publikowane i żadna działająca postać się nie zmienia.

