Jak chronić UI testy przed zmianami frontendu

0

Kontekst:

Mam skomplikowany produkt. Serwer i jakieś małe klienciki zbierające dane w C++.
Dane są prezentowane użytkownikowi przez stronę www - front-end wykonany nodejs ....
QA team dostarczyło testy, które weryfikują wszystko razem - bardzo zasobo chłonne. Czasowo jest około 2h.

Testy jednostkowe są w miarę szybkie: backend 2-3 minuty, front-end poniżej minuty.
Są jeszcze integracyjne tylko dla elementów backend i te zajmują już dużo czasu: 2h dla każdej konfiguracji (konfiguracje uruchamiane równolegle i wymagają tylko jednej maszyny).

Problem

Zespół od front-endu modyfikuje coś i psuje testy QA bo zmieniają się id elementy UI. Napisane python + selenium.
Teraz szukam dobrego sposobu, by jak front-end coś zmieni to Jenkins będzie wstanie szybko zweryfikować, że UI testy nie zostaną popsute.
Najlepiej bez uruchamiania tych testów, bo testy od QA wymagają +10 maszyn i nie ma ich na tyle, żeby przełknąć normalny dzienny przerób Pull Request'ów (PR).

Pytanie

Szukam sposobu, by developer front-endu dostał szybko po łapkach jeśli jego zmiany powodują trudności z odnalezieniem elementu UI.
Tak, żeby poprawił testy UI przed weryfikacją PR.
Uruchamianie testów UI dla każdego PR byłoby zbyt bolesne (za mało zasobów i zje dużo czasu)
Szukam gotowych rozwiązań.

Trudno mi dostarczyć więcej szczegółów, bo odpowiadam za backend (C++) oraz Jenkinsa (groovy), który robi weryfikację Pull Request'ów (dlatego problem trafił miedzy innymi do mnie).

1

Testy które są takie ciężkie są problemem samym w sobie, czego widzisz konsekwencje.

Nie wiem czy istnieje cokolwiek co możesz teraz zrobić.

0

Ciężko mi dywagować na temat interfejsu webowego i java script ale powiem Ci jak ja to zrobiłem u siebie.

Aplikacja zbudowana jest w delphi (GUI) ale nie jeden duży exe tylko bardzo dużo małych modułów podzielonych na BPL'e każdy BPL to tak technicznie oddzielny dproj i oddzielny katalog. Nie mniej w momencie gdy w GITEA (tam mamy CR) pojawi się PR GITEA poprzez webhooka wysyła JSON'a do Jenkinsa. Mając zatem kompletnego JSON'a z GITEA wiem co to za PR, wiem jakie pliki zostały zmienione, którego BPL'a dotyczą, mam numery i hashe poszczególnych gałęzi git więc prostym poleceniem diff (z gita) pobieram listę plików ze statusami (A M D) i wiem, które projekty (BPL'e) powinny zostać przekompilowane w ramach danego PR. Następnie uruchamiam konsolową kompilację poszczególnych BPL i zwrotnie do GITEA (dla danego PR) odkładam informacje o poprawnej lub niepoprawnej kompilacji danego PR w formie komentarz. W przypadku niepowodzenia jest też link do outputa z konsoli konkretnego zadania jenkinsowego. W takim rozwiązaniu nie muszę przy każdym PR przekompilowywać wszystkiego. Ponadto sam test kompilacji też się uruchamia automatycznie. Niestety takich typowych testów GUI nie ma (dlaczego nie ma to temat na oddzielną dyskusję) natomiast odpowiednio parsując informacje wpadające do JENKINSa powinieneś wiedzieć mniej więcej, które elementy GUI zostały zmienione, a co za tym idzie, które testy wymagają uruchomienia lub w przypadku błędów poinformowania developera o konieczności modyfikacji testów.

0

Nie wiem jakiej biblioteki używacie do testowania frontendu, bo jest ich trochę :D ale zazwyczaj Frontendowcy mogą robić coś na zasadzie snapshotów https://jestjs.io/docs/snapshot-testing

W Jest działa to w taki sposób, że tworzymy przykładowy test

import renderer from 'react-test-renderer';
import Link from '../Link';

it('renders correctly', () => {
  const tree = renderer
    .create(<Link page="http://www.facebook.com">Facebook</Link>)
    .toJSON();
  expect(tree).toMatchSnapshot();
});

biblioteka do testów zapisuje strukturę komponentu html do osobnego pliku

exports[`renders correctly 1`] = `
<a
  className="normal"
  href="http://www.facebook.com"
  onMouseEnter={[Function]}
  onMouseLeave={[Function]}
>
  Facebook
</a>
`;

i w przypadku jakiejkolwiek zmiany tej struktury testy nie przechodzą.

Developer musi sprawdzić, czy zmiana jest prawidłowa i odpalić testy jeszcze raz z dodatkową flagą jest --updateSnapshot

0
Xarviel napisał(a):

Nie wiem jakiej biblioteki używacie do testowania frontendu, bo jest ich trochę :D ale zazwyczaj Frontendowcy mogą robić coś na zasadzie snapshotów https://jestjs.io/docs/snapshot-testing

W Jest działa to w taki sposób, że tworzymy przykładowy test

import renderer from 'react-test-renderer';
import Link from '../Link';

it('renders correctly', () => {
  const tree = renderer
    .create(<Link page="http://www.facebook.com">Facebook</Link>)
    .toJSON();
  expect(tree).toMatchSnapshot();
});

Snapshoty są nieodporne na refactor

1
Riddle napisał(a):
Xarviel napisał(a):

Nie wiem jakiej biblioteki używacie do testowania frontendu, bo jest ich trochę :D ale zazwyczaj Frontendowcy mogą robić coś na zasadzie snapshotów https://jestjs.io/docs/snapshot-testing

W Jest działa to w taki sposób, że tworzymy przykładowy test

import renderer from 'react-test-renderer';
import Link from '../Link';

it('renders correctly', () => {
  const tree = renderer
    .create(<Link page="http://www.facebook.com">Facebook</Link>)
    .toJSON();
  expect(tree).toMatchSnapshot();
});

Snapshoty są nieodporne na refactor

Tak, są nieodporne i z tym się zgadzam, bo wszystko zależy od developera, który akurat to testuje, ale według mnie warto o nich wspomnieć. Najwyżej @MarekR22 uzna, że jest to słaby pomysł i będzie szukać czegoś innego

Proces wygląda w taki sposób, że:

  1. biblioteka wykrywa zmianę struktury w danym komponencie
  2. informuje o tym frontendowca
  3. on decyduje, czy zmiana może wpłynąć na wynik testów od QA, jeśli tak to może wycofać zmianę, jeśli nie może puścić to dalej
  4. żeby zaktualizować snapshoty musi uruchomić jeszcze raz polecenie z dodatkową flagą. W bibliotece, którą podlinkowałem to byłoby coś takiego jest --updateSnapshot

Zaleta tych testów jest taka, że można sprawdzić zmianę selektora w kilka minut i nie trzeba uruchamiać testów od QA, które trwają 2 godziny. Wszystko zależy od tego jak będziemy z nich korzystać.

0

Słabe podejście.

Testy powinny testować intencje, zachowanie i cele a nie takie szczegóły implementacyjne jak bebechy które sprawdzają snapshoty.

Testy trwające długo są problemem samym w sobie.

1

Mam w sumie jeszcze jeden pomysł, ale może się okazać, że to również

Riddle napisał(a):

Słabe podejście.

albo nawet jeszcze gorsze :D bo obecnie, żeby to dodać trzeba będzie zmodyfikować część selektorów w testach na bardziej uniwersalne, więc może być już trochę za późno :p

Zgaduje, że do tej pory QA tworzyło selektory głównie po klasach .container > p, .container > button

<div class="container">
  <p>Lorem ipsum</p>

  <button>Lorem ipsum</button>
</div>

i gdy zachodziła potrzeba zmiany wyglądu to załóżmy, że frontendowiec zmienia klasę z container na wrapper

<div class="wrapper">
  <p>Lorem ipsum</p>

  <button>Lorem ipsum</button>
</div>

więc stare selektory w testach automatycznie przestają działać .container > p, .container > button.

Niektóre narzędzia frontendowe takie jak babel mają wtyczki (https://www.npmjs.com/package/babel-plugin-jsx-remove-data-test-id) do generowania testowych atrybutów, których można użyć do tworzenia selektorów. Wtyczkę można skonfigurować w taki sposób, żeby zezwalała na te dodatkowe atrybuty jedynie w testach jednostkowych / e2e, a przy wersji produkcyjnej je kasowała i żeby nie było po nich żadnego śladu.

Wyglądałoby to w taki sposób, że trzeba byłoby dodać data-test-id / data-test-class do elementów w komponencie, chociaż nazwa tego atrybutu może być w pełni dowolna

<div class="container" data-test-id="box">
  <p data-test-id="box-paragraph-1" data-test-class="box-paragraph">Lorem ipsum</p>
  <p data-test-id="box-paragraph-2" data-test-class="box-paragraph">Lorem ipsum</p>

  <button data-test-id="box-button">Lorem ipsum</button>
</div>

Jest to o tyle lepsze od zwykłego id, ponieważ te atrybuty data-* mogą się bez problemu powtarzać i raczej raz nazwany element nie musi być już więcej zmieniany.

.container > p -> [data-test-id="box"] > [data-test-class="box-paragraph"]
.container > button. -> [data-test-id="box"] > [data-test-id="box-button"]

0
Riddle napisał(a):

Słabe podejście.

Testy powinny testować intencje, zachowanie i cele a nie takie szczegóły implementacyjne jak bebechy które sprawdzają snapshoty.

Testy trwające długo są problemem samym w sobie.

Popieram w 100% i takie testy są, które testują elementy systemu osobno (lub mniejszej grupie).

QA zamiast klikać ręcznie powinno mieć zautomatyzowane testy, które testują wszystko od początku do końca (produkt jako całość).
Nieważne jak są powolne i tak bedą szybsze i bardziej pewne niż człowiek. Problemem jest utrzymanie ich w zdrowiu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1