Angular: Integration Testing (pengujian Dangkal)



Ketika aplikasi tumbuh, atau sangat penting bagi kami bahwa ia bekerja dengan benar dengan refactoring apa pun, kami mulai berpikir tentang pengujian unit atau e2e.

Selama beberapa tahun bekerja dengan Angular - aplikasi di segmen korporat, setelah mengalami banyak masalah ketika melakukan refactoring dan membuat fungsionalitas baru, tes tidak tampak seperti buang-buang waktu, tetapi kunci stabilitas di tangan programmer.

Selanjutnya, mari kita coba memahami cara menguji aplikasi dasar pada Angular dan menyentuh sedikit teori.

Mari kita mulai dengan jenis pengujian yang dapat dilakukan oleh pengembang aplikasi (dalam kasus kami, frontend).



(Martin Fowler dan Google Testing Blog)

Angular memiliki metode seperti itu di luar kotak.

Mari kita lihat lebih dekat pada piramida pengujian menggunakan contoh aplikasi Angular.

Unit testing - pengujian terisolasi metode kelas. Kami memeriksa operasi metode, melewati berbagai kombinasi parameter ke input, dan membandingkan hasilnya dengan yang diharapkan.

Sebagai contoh, kami memiliki komponen di mana string hex dikonversi menjadi rgb, informasi ini ditampilkan kepada pengguna, dan juga dikirim ke server lain.

Jika kita mulai mencari tes unit, maka kita dapat menulis banyak tes untuk setiap metode di kelas komponen.

Jika kita memiliki metode rgbToHex (hex: string) => string, maka untuk menguji metode dengan tanda tangan seperti itu, kita perlu melakukan hal berikut: ekspektasi (rgbToHex ('777')). ToBe ('rgb (119, 119, 119)') .

Tampaknya hebat, tetapi kami memiliki masalah karena sejumlah besar fungsi yang perlu dibahas, dan kami terlalu malas untuk menulis tes. Selain itu, bahkan menulis unit test untuk setiap metode dalam suatu komponen, kami tidak menjamin kebenaran kerja sama mereka.

Misalnya, setelah membuat dan menguji komponen output tabel, kita dapat menyebutnya dalam komponen "kalkulator", tetapi secara tidak sengaja menentukan pengikatan yang salah. Maka data tidak akan jatuh ke dalam tabel, dan komponen yang berfungsi penuh tidak akan berfungsi dengan benar.

gambar

Tes integrasi- Menguji banyak komponen. Dari tahap ini kita mulai menguji tidak hanya metode kelas, tetapi juga mengikat mereka ke html, yaitu klik pada elemen di dalam komponen. Pengujian dangkal sering ditemukan dalam notasi sudut , yang pada dasarnya adalah pengujian integrasi.

Pada pengujian Dangkal kami akan membahas lebih detail di bawah ini. Pengujian

E2E (ujung-ke-ujung) - cara untuk menguji aplikasi sepenuhnya untuk menyelesaikan masalah-masalah tes unit.

Dengan pendekatan ini, kami menulis skrip uji untuk aplikasi yang diberikan sepenuhnya, mis. semua komponen dan layanan dirakit bersama, dan kami mereproduksi tindakan pengguna.
Ini sangat keren, tetapi kita mungkin memiliki masalah mengubah bertopik secara dinamis (biasanya server json statis pada node.js), dan untuk memainkan situasi yang berbeda, kita mungkin memerlukan data berbeda dari server yang ditiru.

Misalnya: kami memiliki halaman dengan daftar pengguna, salah satu komponen panel ini adalah pagination. Itu harus berperilaku berbeda dengan jumlah pengguna yang berbeda. Tetapi jika data pada server yang diemulasi diatur melalui json, maka jumlah pengguna akan selalu satu, dan kami tidak akan dapat memeriksa semua kasus dengan jumlah halaman yang berbeda.

Sebagai hasilnya, kita dapat menyimpulkan bahwa jika kita ingin secara fleksibel mengubah bertopik dan menguji bukan dengan metode, tetapi dengan unit logis dari antarmuka, kita perlu menggunakan sesuatu di antara e2e dan unit-tes. Di sinilah pengujian dangkal (pengujian integrasi) datang untuk menyelamatkan.

Glosarium:

  • Mock adalah objek untuk mensimulasikan respons dalam berbagai kasus penggunaan.
  • Rintisan bertopik adalah rintisan paling bodoh tanpa logika (Anda dapat membaca Martin).
  • Karma adalah pelari ujian yang dibangun dalam sudut (sering disarankan untuk menggunakan lelucon sebagai gantinya, tetapi tidak tentang itu hari ini).
  • Jasmine adalah kerangka kerja untuk menggambarkan tes dalam bentuk spesifikasi (lihat di bawah).
  • ekstensi file uji - spesifikasi (deskripsi spesifikasi dalam gaya BDD).
  • itu adalah nama metode untuk tes di Jasmine.
  • xit adalah nama metode yang tidak akan berjalan.
  • cocok - jika ada metode dengan nama yang sama dalam spesifikasi, hanya mereka yang akan diluncurkan.

Pengujian dangkal untuk Angular, serta kerangka kerja lainnya, adalah pendekatan unit-test, ketika komponen dengan ukuran cukup besar ditampilkan sehingga dapat ada sebagai unit ui yang terpisah dengan fungsionalitasnya sendiri.

Sebagai contoh, kami memiliki komponen untuk mengonversi hex -> rgb. Kami hanya dapat membuat komponen ini, menghasilkan bertopik untuk situasi yang berbeda, mengeksekusi kasus penggunaan yang mungkin untuk komponen ini dari sudut pandang pengguna akhir dan memeriksa operasi komponen.

Mari kita coba cari contoh (repositori).

Mempersiapkan kelas untuk mengakses komponen komponen sesuai dengan PageObject dan menambahkan pembantu ke akar proyek.

Helper - akan membantu mencari elemen dalam komponen yang telah dipilih untuk dirender. Dengan cara ini kita dapat membuat hidup lebih mudah jika kita menggunakan Bahan Angular: maka elemen tipe pilih akan membuat daftar dengan opsi di blok terpisah, dan mencari elemen-elemen ini dapat menyebabkan pelat ketel, dan pembungkus dalam bentuk helper dapat membantu.

export class PageObjectBase {

  constructor(private root: HTMLDivElement) { }
  //    input  
  _inputValue(cssSelector: string, value: string) { 
    if (value) {
      this.root.querySelector<HTMLInputElement>(cssSelector).value = value;
      this.root.querySelector<HTMLInputElement>(cssSelector).dispatchEvent(new Event('input'));
    }
    else {
      return this.root.querySelector<HTMLInputElement>(cssSelector).value
    }
  }
  //          
  _buttonClick(cssSelector: string) {
    this.root.querySelector<HTMLButtonElement>(cssSelector).dispatchEvent(new Event('click'));
  }

}

PageObject adalah templat pengujian otomatis populer. Digunakan untuk menyederhanakan dukungan untuk tes tertulis. Jika kami mengubah UI, maka kami tidak perlu menulis ulang tes, cukup ubah pemilih elemen.


export class ConverterFromHexPageObject extends PageObjectBase {

  constructor(root: HTMLDivElement) {
    super(root)
  }

  hex(text?: string) {
    return this._inputValue('.input-hex', text);
  }

  rgb(text?: string) {
    return this._inputValue('.input-rgb', text);
  }

  clear() {
    this._buttonClick('.btn-clear')
  }

  calc() {
    this._buttonClick('.btn-calc')
  }

}

dan tes itu sendiri:


// ,        api   
const urlToSave = 'http://localhost:4200/save-hex';


//  -   
describe('ConverterFromHexComponent', () => {
  let component: ConverterFromHexComponent;
  let fixture: ComponentFixture<ConverterFromHexComponent>;
  let page: ConverterFromHexPageObject;
  let httpTestingController: HttpTestingController;


  //      ,   
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ConverterModule, HttpClientTestingModule]
    })
      .compileComponents();
    httpTestingController = TestBed.get(HttpTestingController);
  }));


  //  ,   
  beforeEach(() => {
    fixture = TestBed.createComponent(ConverterFromHexComponent);
    component = fixture.componentInstance;
    page = new ConverterFromHexPageObject(fixture.nativeElement);
    fixture.detectChanges();
  });


  //    ,     http 
  afterEach(() => {
    httpTestingController.verify();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should clear', async () => {
    page.hex('112233'); //  input  
    expect(page.hex()).toBe('112233'); // ,    
    await page.clear(); //      
    fixture.detectChanges(); //    
    expect(page.hex()).toBe(''); // ,   clear 
  });

  it('should convert', async () => {
    page.hex('123123');
    expect(page.rgb()).toBe('');
    page.calc();
    const req = httpTestingController.expectOne(urlToSave);
    expect(req.request.method).toEqual('POST');
    expect(req.request.body.hex).toEqual('123123');
    req.flush({});
    await fixture.detectChanges();
    expect(page.rgb()).toBe('rgb(18, 49, 35)');
  });

  it('should convert three-digit hex', async () => {
    page.hex('567');
    expect(page.rgb()).toBe('');
    page.calc();
    const req = httpTestingController.expectOne(urlToSave);
    expect(req.request.method).toEqual('POST');
    req.flush({});
    await fixture.detectChanges();
    expect(page.rgb()).toBe('rgb(85, 102, 119)');
  });

  it('rgb should be empty when entered incorrectly hex', async () => {
    page.hex('qw123we');
    page.calc();
    const req = httpTestingController.expectNone(urlToSave);
    await fixture.detectChanges();
    expect(page.rgb()).toBe('');
  });

});

Segalanya tampak sederhana, tetapi di sini ada beberapa catatan menarik untuk pengujian Angular Dangkal:

  • Selalu periksa bahwa tidak ada permintaan http tanpa pagu harga, ini akan membantu Anda untuk memahami dengan tepat jika ada permintaan yang tidak perlu untuk fungsi kami.
  • PageObject , .
  • json , .
  • , .
  • .
  • .
  • , session, local, cookie ( ).
  • fake.js.
  • .




Source: https://habr.com/ru/post/undefined/


All Articles