Sobes.tech
Middle

Dlaczego nie można używać słowa kluczowego 'this' w kontekście automatyzacji testów?

sobes.tech AI

Odpowiedź od AI

W kontekście automatyzacji testów w JavaScript, słowo kluczowe this nie jest zalecane do przechowywania lub przekazywania danych o stanie testu (np. aktualny użytkownik, status autoryzacji, informacje o stronie), ponieważ:

  1. Nieprzewidywalny kontekst: Wartość this jest określana przez to, jak wywoływana jest funkcja, a nie przez miejsce jej deklaracji. W kodzie asynchronicznym (Promises, async/await, callbacki) lub przy użyciu funkcji strzałkowych, wartość this może być inna niż oczekujesz. To utrudnia debugowanie i utrzymanie kodu.

  2. Zależność od środowiska: W różnych frameworkach testowych (Mocha, Jest, Cypress) i w zależności od ustawień (tryb ścisły), kontekst this może zachowywać się różnie. To utrudnia przenośność kodu.

  3. Złożoność równoległego wykonywania: Przy równoległym wykonywaniu testów z użyciem tego samego egzemplarza klasy testowej lub obiektu, this może być nadpisany przez inny wątek wykonania, co prowadzi do warunków wyścigu i niepoprawnych wyników.

Zamiast używać this, lepiej jest:

  • Używać zmiennych lokalnych w ramach testów.
  • Przekazywać zmienne jako argumenty do funkcji pomocniczych.
  • Używać specjalistycznych obiektów lub klas do przechowywania stanu (np. Page Objects).
  • Używać zmiennych globalnych lub singletonów (ostrożnie, tylko jeśli konieczne).

Przykład problemu z this w kodzie asynchronicznym:

// Przykład z Mocha
describe('Test autoryzacji', function() {
  this.currentUser = null; // Stan przechowywany w `this`

  it('powinien się zalogować', async function() {
    await login('testUser', 'password');
    this.currentUser = 'testUser'; // `this` odnosi się do kontekstu testu
  });

  it('powinien sprawdzić profil', async function() {
    // Tutaj `this` NIE BĘDZIE zawierać currentUser,
    // jeśli test 'powinien się zalogować' wykonał się asynchronicznie
    // lub jeśli kontekst funkcji się zmienił
    console.log(this.currentUser); // Może być null lub undefined
  });
});

Lepszy przykład: przekazywanie danych jako argumentów lub użycie Page Objects:

// Funkcja pomocnicza
async function checkUserProfile(userName) {
  // Logika sprawdzania profilu dla konkretnego użytkownika
}

describe('Test autoryzacji', function() {
  it('powinien się zalogować i sprawdzić profil', async function() {
    const user = 'testUser';
    await login(user, 'password');
    // Przekazanie użytkownika jako argumentu
    await checkUserProfile(user);
  });
});