Przejdź do treści

Neos Inspector

Neos Inspector jest narzędziem wspomagającym pracę developera. Pozwala podglądać szczegóły techniczne dotyczące otwartych okien aplikacji,a od wersji 6.3 umożliwia także nagrywanie programowych testów i skyptów do generowania danych.

Podgląd szczegółow technicznych

Za pomocą inspektora można uzyskać informację o bieżącym stanie otwartych okien aplikacji. Aby uruchomić inspektora należy wybrać przycisk w górnym menu aplikacji Developer->Pozostałe->Neos Inspektor. Jeśli tym narzędziem chciałbyś zbadać stan okna modalnego, to najpierw uruchom Neos Inspectora, następnie uruchom okno modalne, a następnie odśwież drzewo Neos Inspectora. Chodzi o to, że gdybyś najpierw uruchomił okno modalne, to nie masz już dostępu ani do wstążki ani do żadnych innych okien i nie będziesz w stanie uruchomić Neos Inspectora. Poza tym, jeśli Neos Inspector jest aktywny, to okna modalne są automatycznie zamieniane na okna wolne. Dzięki temu po uruchomieniu okna deklarowanego jako modalne, będziesz dalej w stanie pracować na Neos Inspectorze.

Okno inspektora składa się z trzech części.

  1. U góry widoczne są przyciski z możliwymi akcjami do wyboru.
  2. Część środkowa zawiera drzewo aktualnie otwartych okien. Po rozwinięciu gałęzi widoczne są dodatkowe informacje tj. źródła danych, z których korzysta okno, pola danych, parametry.
  3. Część dolna wyświetla informacje o stanie wybranego elementu. W szczególności możemy uzyskać dane na temat stanu okna, stanu źródła danych oraz dane zaawansowane.

Każda forma tworzona w technologi Neos posiada źródło danych. Jeśli uruchomione okno składa się z kilku zagnieżdżonych form to będzie zawierało źródła danych każdej z tych form. Dodatkowo jeśli na formie znajduje się komponent combobox, którego wartościami są pola z bazy danych to dla tego komponentu zostanie utworzone dodatkowe źródło danych(widoczne w drzewie inspektora z ikonką combobox). Inspektor pozwala sprawdzić jakie źródła danych są podpięte do okna oraz umożliwia sprawdzenie jakie zapytanie lub jaki filtr jest nałożony na wybrane źródło danych. Dodatkowo po rozwinięciu w źródle danych gałęzi z polami można zaobserwować, na które pole nałożony jest kontekst(pola z kontekstem są wytłuszczone). Jest to szczególnie przydatne w przypadku, gdy developer chce sprawdzić dlaczego nie działa tworzona funkcjonalność, np. w oknie nie pokazują się dane, albo nie uruchomiła się jakaś metoda zależna od wartości parametru.

Przykład

Testujemy okno SENTE.PODMIOT (BROWSE). Dla podmiotu "Rapcewicz Natalia" nie pokazują się dane kontaktowe. W inspektorze przechodzimy do okna Podmioty CRM, a następnie odszukujemy źródło danych Sente.Kontakt(BROWSE). Widać, że to źródło danych działa na tabeli KONTAKTY oraz ma nałożony filtr CPODMIOT = '7969'. Dzięki takiej informacji łatwo możemy sprawdzić za pomocą IBExperta, że w bazie danych w tabeli KONTAKTY nie ma wpisów gdzie pole CPODMIOT = '7969'.

Formy

Istawiając się w drzewie obiektów na formie, w dolnej części dostępne będą następujące informacje:

Styl formy

  • forma MDI
  • forma dialogowa stała
  • forma dialogowa zmienna
  • forma okna wolnego

Tryb

  • zwykła forma do przeglądania danych
  • forma do edycji z przyciskami Zapisz, Anuluj
  • forma do wyboru ze słownika

Źródła danych

ustawiając się w drzewie na źródle danych(element z ikonką walców) dostępne będą następujące informacje:

Baza danych - informacja do jakiej bazy danych podłączony jest dataset

Tabela - wyświetal informacje o tabeli jeśli dataset operuje na tabeli bazy danych

Stan - określa stan źródła danych, poszczególne identyfikatory odpowiadają wartościom:

  • B - Browse
  • E - Edit
  • I - Insert
  • D - Delete

Zapytnie/Filtr - jeśli dataset operuje na tabeli to pokazuje filtr, a jeśli dataset operuje na zapytaniu to pokazuje treść zapytania

Utworzony programowo - informuje czy źródło danych powołano na podstawie definicji czy programowo np. w kodzie uruchomiono nowe okno za pomocą funkcji ShowForm()

Tylko do odczytu - informuje czy w źródle danych można zapisywać zmiany

Pola danych

Rozwijając w drzewie gałąź Pola możemy uzyskać informację o istotnych polach źródła danych. W drzewie bezpośrednio za nazwą pola znajduje się aktualna wartość pola w bieżącym rekordzie. Jeśli wartość pola jest pobrana za pomocą relacji, to po znaku równości będzie widoczna aktualna wartość pola, po którym wykonano złączenie(ID), a w nawiasach kwadratowych wartość wyświetlana. Dodatkowo pola, na które nałożono kontekst są wytłuszczone. Trzeba pamiętać, że Inspektor pokazuje jedynie pola śledzone przez serwer, np. pola wykorzystywane w metodach. (Aby wymusić śledzenie pola należy w definicji rozwinąć panel Walidacja i zaznaczyć Używane w skrypach)

Parametry

W gałęzi Parametry możemy sprawdzić bieżący stan zadeklarowanych parametrów obiektu. Parametry podobnie jak pola danych pokazują bezpośrednio za nazwą parametru aktualną wartość.

Akcje

- odświeża okno Neos Inspektora

- jeśli otwarty jest Neos Expert to ustawia się na definicji obiektu

- jeśli otwarty jest Neos Expert to ustawia się na definicji okna

- włącza/wyłącza tryb developera

- otwiera okno definicji pola/parametru

Nagrywanie testów programowych i skryptów

Nagrywanie testów i skryptów w Neosie umożliwia automatyzację testowania i generowanie powtarzalnych scenariuszy użytkownika, co znacznie ułatwia proces weryfikacji i zapewnienia jakości aplikacji. Funkcja nagrywania testów programowych i skryptów jest dostępna od wersji 6.3.

Wewnętrzne szkolenie z tego mechanizmu jest dostępne na tym filmie.

Włączanie trybu nagrywania

Aby włączyć tryb nagrywania w Neosie, należy użyć przycisku "Nagraj test GUI". Po jego aktywowaniu, nagrywane są wszystkie działania użytkownika w aplikacji, jednak dotyczy to wyłącznie elementów Neosowych. Klikanie po oknach nie-neosowych nie jest rejestrowane.

Czynności podlegające nagraniu

Podczas nagrywania, rejestrowane są następujące czynności:

  • Klikanie w funkcje we wstążce: nagrane jako wywołanie metody statycznej akcji wstążki.
  • Klikanie w akcje na formie lub w popup menu: wywołanie akcji lub metody niestatycznej przypisanej do akcji.
  • Uzupełnianie pól/parametrów: przypisywanie programowe wartości.
  • Ustawienie się na rekordzie w gridzie: wywołanie metody FindRecord(...), znajdującej ten rekord programowo.

Zakończenie nagrania

Po zakończeniu nagrania, można skopiować wygenerowany kod do schowka i wkleić go do metody statycznej interfejsowej obiektu biznesowego. Aby kod działał poprawnie, należy pamiętać o kilku kwestiach:

  • Projekt, do którego wklejamy kod, musi mieć referencje do projektów, z których pochodzą klikane elementy oraz referencję na projekt NEOSTEST.
  • Kod miejscami wywołuje funkcję RefreshClientAndWait, aby poczekać na synchronizację z klientem.
  • Synchronizacja działa poprawnie jedynie dla kodu wywołanego w osobnym wątku, czyli przez RunAsync.
  • Synchronizacja nie działa poprawnie dla okien modalnych. Aby poprawnie działało odtwarzanie testu zawierającego klikanie po oknach modalnych, należy wcześniej uruchomić okno Neos Inspectora. Otwarty Neos Inspector powoduje, że okna modalne są zamieniane na okna wolne, w których poprawnie działa zarówno nagrywanie testów, jak i ich odtwarzanie.
  • Zwykle należy z kodu wyciąć nadmiarowe wywołania funkcji FindRecord, lub też zmienić pola po których odbywa się wyszukiwanie rekordów. Domyślnie generowane jest wyszukiwanie po polach klucza głównego. Ale jeśli dane dochodzą w trakcie testu, to wartości pola REF nie da się przewidzieć z góry. Dlatego wtedy należy przełączyć wyszukiwanie na jakieś inne pole, o z góry znanej treści.
  • Uzupełnić kod o niezbędne asercje.

Zalecenia podczas nagrywania testów

Podczas nagrywania testów warto trzymać się następujących zasad:

  • Każdy test zaczynać od kliknięcia we wstążkę, aby otworzyć te okna, na których chcemy działać. Nie zaczynać od klikania na już otwartych oknach, gdyż mogą mieć jakiś zastany kontekst, którego test nie odtworzy.
  • Każdy test kończyć zamykaniem tych okien, które w ramach testu otwarto, aby stan aplikacji po zakończeniu testu był taki, jak przed jego rozpoczęciem.
  • Nazwać metodę testową, tak aby było jasne, co robi.
  • W nazwie metody zaszywać liczby, tak aby kolejność metod testowych według ich nazw alfabetycznych była zgodna z pożądaną kolejnością uruchomienia kolejnych testów.

Przykład nagranego testu

Poniższy przykład pochodzi z nagrania wejscia do okna "Moje zadania" z projektu WORKFLOW oraz założenia nowego zadania dla użytkownika "Adrian Górecki".

[TestMethod]
public static void Test01_NoweZadanieDlaAdrianGorecki()
{
GUI.RunAsync( param => {

  // Uruchom metodę statyczną podpiętą do akcji we wstążce.
  WORKFLOW.WFACTIVITYLIST.ShowTaskList();

  var wfactivitylist = GUI.GetObjectInstances<WORKFLOW.WFACTIVITYLIST>("WORKFLOW.WFACTIVITYLIST").FirstOrDefault(o => o.FormName=="TASKLIST");
  wfactivitylist.RefreshClientAndWait(2000);

  // Wywołaj akcję z obiektu biznesowego.
  wfactivitylist.Actions.ShowNewRecord.Invoke();
  // Wywołaj metodę skojarzoną z akcją utworzoną dynamicznie.
  wfactivitylist.InternalShowForm4NewActivity("99");

  var wfnewactivity = GUI.GetObjectInstances<WORKFLOW.WFNEWACTIVITY>("WORKFLOW.WFNEWACTIVITY").FirstOrDefault(o => o.FormName=="EDIT");
  wfnewactivity.RefreshClientAndWait(2000);

  wfnewactivity._name = "Test zadania 1";
  // Wywołaj akcję predefiniowaną neosa (taką, która nie ma swojej metody w obiekcie).
  wfnewactivity.Actions.Invoke("312d6a903bc64232a2d8e40ee5455bccSHOWDICT");

  var wfgetroles4activity = GUI.GetObjectInstances<WORKFLOW.WFGETROLES4ACTIVITY>("WORKFLOW.WFGETROLES4ACTIVITY").FirstOrDefault(o => o.FormName=="BROWSE");
  wfgetroles4activity.RefreshClientAndWait(2000);


  // Programowo znajdź rekord w gridzie, który został kliknięty w trakcie nagrywania
  wfgetroles4activity.SearchValue = ""; // wyczyść pole wyszukiwania w gridzie
  wfgetroles4activity.FindRecord(new Contexts().Add("ID","1ea2a42f494049dcb3edac4ed7df2572"));
  wfgetroles4activity.RefreshClientAndWait(2000);

  // Wywołaj akcję predefiniowaną neosa (taką, która nie ma swojej metody w obiekcie).
  wfgetroles4activity.Actions.Invoke("RESULT");
  wfnewactivity._priority = "1";
  // Wywołaj akcję z obiektu biznesowego.
  wfnewactivity.Actions.PostRecord.Invoke();
  // Wywołaj akcję z obiektu biznesowego.
  wfactivitylist.Actions.CloseRecord.Invoke();
});  
}