Służy on do tego aby sprawdzać czy dane tabeli sie ajaxowo odświeżyły.
Przykładowy test:
[code=ruby] it ‘should filter members’ do
other = create :member
filtered = create :member, name: ‘Filter’
visit members_path
within '#members_list_filter' do
fill_in 'Search', with: 'Filter'
end
wait_for_datatable_processing
within('table#members_list') do
expect(page).to have_content filtered.name
expect(page).not_to have_content other.name
end
end[/code]
Test ten jest bardzo wolny i o ile na mojej maszynie przechodzi to na kolegi już nie. Czy można to jakoś uprościć ewentualnie jakieś inne podejście ?
Nie jestem tego pewien, ale możliwe jest, że możesz tu mieć race condition. Kiedy ten kod będzie wykonywany ‘page.should have_selector ‘div’, text: “Processing…”, visible: true’ w przeglądarce tekst “Processing…” może (ale nie musi) być już widoczny.
Ja żeby testować datatables tylko testuje w integracji fakt, że działają. A szukanie i filtrowanie testuje na poziomie controllera (czy json w odpowiednim formacie został zwrócony).
[code] #integration test
it ‘should populate table with members’ do
member = create :member
within('table#members_list') do
expect(page).to have_content member.name
end
end[/code]
[code]
controller test
before do
create(:member, name: ‘foo’)
create(:member, name: ‘bar’)
create(:member, name: ‘baz’)
end
it ‘returns 2 rows without “foo”’ do
get :index, params(format: :json, sSearch: “ba”, iDisplayStart: ‘0’, iDisplayLength: ‘25’)
body = response.body
body.should_not include ‘foo’
ActiveSupport::JSON.decode(body)[‘aaData’].count.should == 2
end[/code]
Oczywiście na poziomie controllera zamiast stworzyć rekordy w bazie możesz je po prostu zmokować. Ale ja mam dosyć skomplikowany kod który filtruje, stronicuje i zwraca odpowiedni json. Stąd wolę przetestować wszystko.
Dzięki. Wolałbym jednak testować to w testach funkcjonalnych, czasem drobna zmiana w js może spowowodować że tabele sie nie pokażą, mimo że json jest zwracany. Problemem tu jest phantomjs który jeszcze nie ze wszystkim radzi sobie idealnie.
Ajax.
Samo wyświetlanie rekordów zaraz po wejściu na strone działa ok i testuje sie poprawnie.
Problem jest w tym że czasem phantomjs/capybara (?) nie czeka aż dane się załadują, np po sortowaniu lub wyszukiwaniu rekordu i od razu chce sprawdzać czy tekst istnieje, czasem test przechodzi a czasem nie, losowo. Przykładowy test
[code=ruby] it ‘should filter members’ do
other = create :member
filtered = create :member, name: ‘Filter’
visit members_path
within '#members_list_filter' do
fill_in 'Search', with: 'Filter'
end
wait_for_datatable_processing # mój helper
within('table#members_list') do
expect(page).to have_content filtered.name
expect(page).not_to have_content other.name
end
end[/code]
Co do testu integracyjne, ten który podałem moim zdaniem jest wystarczający. On po prostu sprawdza czy Datatables załadowało do tabeli dane z serwera. A to czy Datatables te dane posortuje i pofiltruje jest już jego właściwą funkcjonalność, która zostało przetestowana przez autora biblioteki i zakładasz, że działa.
Tak jak mówi asok, na oko masz race condition, jeżeli na komputerze kolegi ajax wykona się szybciej niż pierwsza linijka helpera to test nie przejdzie, z informacją, że nie nie może znaleść div’a z tekstem “Processing…”
Kombinuje z czymś takim. Dodałem callbacki do coffescriptu dla datatables:
fnPreDrawCallback: ->
$(this).removeAttr('draw-finished')
fnDrawCallback: ->
$(this).attr('draw-finished', true)
i sprawdzam w teście czy atrybut sie ustawił:
expect(page).to have_xpath "//table[@id = 'members_list' and @draw-finished = 'true']"
Niestety test wykonuje sie jakies 20 sekund, podobnie jak poprzednia wersja, czyli zdecydowanie za długo.
Odbiegając trochę od głównego tematu które wyszukiwanie w testach jest najszybsze ? have_xpath, have_css a może coś innego ?