Przejdź do treści

Testowanie

Załóżmy, że nasza aplikacja może zostać uruchomiona z określonym stanem Feature Flag. Podobnie należy podejść do uruchamiania testów automatycznych. Jeśli uruchomimy testy automatyczne kilka razy, za każdym razem z innymi ustawieniami flag, otrzymamy kompletny raport z testów naszej aplikacji.

Zaraz, zaraz. Nikt przecież nie będzie generował wszystkich permutacji flag i uruchamiał tych testów!

To prawda. Nie ma takiej potrzeby. Jako twórcy systemu wiemy, które permutacje musimy przetestować, bo zazwyczaj takich, które są istotne "produkcyjnie" jest skończona, mała ilość.

Wiemy jakie ustawienia są aktualnie używane na produkcji. Ten zestaw to pierwsza permutacja, która jest dla nas istotna, i którą należy przetestować automatycznie. Testy automatyczne uruchomione z tym zestawem flag będą pilnować regresji. Będą strażnikiem sprawdzającym, czy nowe zmiany niczego nie popsuły.

Jeśli na produkcji mamy kilka flag operacyjnych lub biznesowych, należy przetestować te części systemu, na które wpływa zmiana tych flag. Chcemy mieć pewność, że zawsze będziemy mogli przełączyć te flagi bez obaw, że aplikacja przestanie działać.

Info

Uruchamianie testów automatycznych można zrównoleglić. Każda konfiguracja może zostać uruchomiona osobno, o ile nasze środowisko na to pozwala i mamy możliwość uruchomienia każdej instancji systemu osobno.

Pisanie testów

Pracując z Feature Flag'ami dochodzi do sytuacji, w której niektóre testy w ogóle nie powinny być uruchamiane, jeśli stan flagi na to wskazuje.

Przykładowo, mamy test end-to-end sprawdzający, czy w naszym interfejsie pojawia się nowa pozycja w menu. Jeśli pojawienie się tego elementu menu jest uzależnione od włączonej flagi, to ten test będzie fail'ował za każdym razem, kiedy zostanie uruchomiony przy zgaszonej fladze. W takiej sytuacji lepiej ten test pominąć. W większości framework'ów można dynamicznie oznaczyć test jako pominięty (skipped).

<?php
class AcmeTest extends TestCase
{
    public function testResponseWithDetailsDisabled()
    {
        if(FeatureFlag::isEnabled('show_details')){
            $this->markTestSkipped("Flag show_details is enabled");
        }

Czasami wynik testów automatycznych może zależeć od stanu flagi. Jeśli mamy test integracyjny, który sprawdza działanie jakiejś części systemu, która w zależności od stanu flagi zwraca dodatkowe dane lub nie, to kuszące staje się uzależnić asercję w teście od stanu flagi.

Takie rozwiązanie, o ile szybkie do wdrożenia, komplikuje test. Lepszym rozwiązaniem jest stworzenie nowego testu obok i uzależnienie uruchomienia obu testów od stanu flagi. Dzięki temu przy włączonej fladze uruchomi się jeden test, testujący nowe zachowanie systemu. Przy wyłączonej fladze uruchomi się drugi test, sprawdzający stare zachowanie systemu.

<?php
class AcmeTest extends TestCase
{
    public function testResponseWithDetailsEnabled()
    {
        if(!FeatureFlag::isEnabled('show_details')){
            $this->markTestSkipped("Flag show_details is disabled");
        }

Uruchamianie testów lokalne

Podczas pracy w modelu Trunk Based Development, testujemy każdy commit lokalnie, zanim wyślemy go do współdzielonego repozytorium.

Jeśli pracujemy nad kodem, który jest schowany za Feature Flag'ą, to przed wysłaniem naszych zmian powinniśmy obowiązkowo uruchomić testy automatyczne bez włączonej naszej flagi. To sprawdzi, czy nie zepsuliśmy systemu i nie wprowadziliśmy regresji naszą zmianą.

Następnie powinniśmy uruchomić testy z włączoną naszą flagą. To sprawdzi, czy włączenie naszej flagi wprowadza regresję w systemie i przy okazji sprawdzi, czy stworzony przez nas kod działa prawidłowo.

Jeśli ta część nie przejdzie testów, należy nasze rozwiązanie ustabilizować, zanim wyślemy kod do współdzielonego repozytorium.

Testowanie przed uruchomieniem nowej funkcji systemu

Jeśli prace nad nową funkcją dobiegają końca i planujemy przełączenie flagi na produkcji, należy dodać nowy, docelowy zestaw flag do testowanych konfiguracji. To ważne, by testować zarówno starą, jak i nową konfigurację.

Być może stosujemy canary deployment i nie wszyscy klienci od razu zobaczą nową funkcję.

Być może dojdzie do sytuacji awaryjnej, w której będziemy musieli wyłączyć flagę, którą przed chwilą włączyliśmy.

W obu scenariuszach chcemy mieć pewność, że system będzie zachowywał się prawidłowo.

Gdy zdecydujemy, że nowa flaga zostaje włączona na stałe i jesteśmy gotowi usunąć ją z kodu, wtedy też pozbywamy się dodatkowej konfiguracji do testów automatycznych.