2012-09-26 17 views
6

Piszę test jednostkowy dla niestandardowego Validatora w QTableView przy użyciu QTestLib framework. Jeden z najbardziej podstawowych przypadków testowych można opisać w następujący sposób:Jak można edytować komórkę QTableView z testu jednostki QTest?

Kliknij dwukrotnie komórkę tabeli w trzeciej kolumnie i czwartym wierszu, a następnie dodaj liczbę "5" do jej zawartości.

Nie wystarczy po prostu zmienić wartość w modelu lub czegokolwiek, sprawa testy wykonują je tak:

  1. kliknij dwukrotnie komórkę tabeli, aby ustawić go w trybie edycji
  2. Naciśnij klawisz [Koniec].
  3. Naciśnij przycisk [5].

Uwaga: This question ma odpowiedź, w jaki sposób ustawić komórkę tabeli w trybie edycji z kodu, jednak testy jednostkowe powinny starać się trzymać z możliwościami ludzkiego użytkownika, to znaczy działania myszy/klawiatury.

Dowiedziałem się, że pozycja X/Y komórki może zostać odzyskana przy użyciu QTableView::columnViewportPosition(int) i QTableView::rowViewportPosition(int). Jednak dwukrotne kliknięcie w określonej lokalizacji za pomocą QTest::mouseDClick(...) ani wybiera komórkę ani ustawia go w tryb edycji:

// Retrieve X/Y coordinates of the cell in the third column and the fourth row 
int xPos = m_pTableView->columnViewportPosition(2); 
int yPos = m_pTableView->rowViewportPosition(3); 

// This does not work 
QTest::mouseDClick(m_pTableView, Qt::LeftButton, QPoint(xPos, yPos)); 

Jak mogę wdrożyć przypadek testowy, który opisałem powyżej, używając tylko myszki działań/klawiatury?

PS: próbuję to pod Windows XP 32 bit i Qt 4.6.1

Odpowiedz

5

Istnieje kilka rzeczy do rozważenia podczas próby edycji w QTableView przez symulowanych zdarzeń:

QTableView nie robi wyświetlać komórki bezpośrednio, robi to za pomocą swojego viewport(). Podobnie zdarzenie z podwójnym kliknięciem musi zostać wysłane do widoku, zamiast samego widoku tabeli.

Teraz kiedy robisz

QTest::mouseDClick(m_pTableView->viewport(), Qt::LeftButton, 
        NULL, QPoint(xPos, yPos)); 

komórka zostanie wybrana, ale nie w trybie edycji (w przeciwieństwie do ludzkiej inicjowanej dwukrotnym kliknięciem który natychmiast stawia komórkę w tryb edycji, nawet jeśli widok tabeli nie mają focus przed). Jeśli dodasz jedno kliknięcie w tym samym miejscu przed dwukrotnym kliknięciem, zadziała to!

Po wysłaniu przycisku [Koniec] do okna ekranu kursor nie przeskoczyłby na koniec zawartości komórki tabeli, ale zamiast tego wybrana zostanie ostatnia komórka w bieżącym wierszu.
Aby zmienić zawartość komórki tabeli, należy zamiast tego wysłać zdarzenie do bieżącego widgetu edytora. Najprostszym sposobem na to jest użycie QWidget::focusWidget()

QTest::keyClick(m_pTableView->viewport()->focusWidget(), Qt::Key_End); 

pamiętać, że korzystanie to tak może być niebezpieczne choć jak focusWidget() może zwrócić NULL.


Z tej wiedzy, w przypadku testu można zaprogramować w następujący sposób:

// Note: The table view must be visible at this point 

// Retrieve X/Y coordinates of the cell in the third column and the fourth row 
int xPos = m_pTableView->columnViewportPosition(2) + 5; 
int yPos = m_pTableView->rowViewportPosition(3) + 10; 

// Retrieve the viewport of the table view 
QWidget* pViewport = m_pTableView->viewport(); 

// Double click the table cell to set it into editor mode 
// Note: A simple double click did not work, Click->Double Click works, however 
QTest::mouseClick (pViewport, Qt::LeftButton, NULL, QPoint(xPos, yPos)); 
QTest::mouseDClick(pViewport, Qt::LeftButton, NULL, QPoint(xPos, yPos)); 

// Simulate [End] keypress 
QTest::keyClick(pViewport->focusWidget(), Qt::Key_End); 

// Simulate [5] keypress 
QTest::keyClick(pViewport->focusWidget(), Qt::Key_5); 

(Uwaga: jeśli chcesz to sprawdzić, można dodać QTest :: qWait (1000) nakazuje po każdym impreza)


Jeśli używasz _data() działa w sposób opisany here, trzeba pamiętać, że nie można odzyskać focusWidget() w momencie tworzenia danych. Rozwiązałem ten problem, tworząc niestandardowy interfejs ITestAction tylko z czystą wirtualną funkcją "wykonaj()". Następnie dodałem podklasy o podobnym konstruktorze, co funkcje QTest::mouseClick(...) etc. Te klasy po prostu wywołują funkcje QTest, ale używają samego widgetu lub jego widgetu skupienia jako parametru, w zależności od dodatkowej flagi boolowskiej. Wstawka _data() przechowuje następnie QList < ITestAction *> dla każdego wiersza danych, a rzeczywisty przedział testowy przechodzi przez iterację nad tą listą i wywołuje polecenie execute() na każdym elemencie przed wykonaniem sprawdzania poprawności.

+0

To jest dokładnie odpowiedź, której potrzebowałem, dziękuję bardzo :) – astrojuanlu

+0

Co to jest + 5 i + 10 dla int - int xPos = m_pTableView-> columnViewportPosition (2) + 5; int yPos = m_pTableView-> rowViewportPosition (3) + 10; – NiladriBose

+1

@NiladriBose: są to liczby pikseli. Ponieważ symulujemy kliknięcia, prawdopodobnie chcemy kliknąć gdzieś w komórce, a nie na jej obramowaniu, aby upewnić się, że wybrana jest właściwa komórka. –

Powiązane problemy