Spis treści

# Usługa SFUnitTests.UnitTest

Usługa UnitTest zapewnia framework do automatyzacji testów jednostkowych z wykorzystaniem języka Basic, obejmujący możliwość:

- Agreguj przypadki testowe w zestawy testów i testy jednostkowe.

- Udostępniaj kod konfiguracji i zamykania pomiędzy przypadkami testowymi.

- Raportuj wyniki testów za pomocą Console.

Zarówno testy jednostkowe, jak i testowany kod muszą być napisane w języku Basic. Testowany kod może wywoływać funkcje napisane w innych językach.

Usługa UnitTest nie jest dostępna dla skryptów Pythona.

## Definicje

### Przypadek testowy

Przypadek testowy to indywidualna jednostka testowania. Sprawdza konkretną reakcję na określony zestaw danych wejściowych.

W usłudze UnitTest przypadek testowy jest reprezentowany przez pojedynczy podstawowy element Sub, którego nazwa zaczyna się od wspólnego przedrostka (domyślnie jest to "Test_").

Przypadek testowy kończy się niepowodzeniem, jeśli jedna z metod AssertX zwróci wartość False.

### Zestaw testowy

Zestaw testowy to zbiór przypadków testowych, które należy wykonać razem.

Wszystkie przypadki testowe zestawu testowego są przechowywane w jednym module Basic.

Zestaw testów może implementować metody SetUp i TearDown w celu przygotowania przypadków testowych w swoim module.

### Test jednostkowy

Pełny test jednostkowy składa się z zestawu zestawów testów w tej samej bibliotece Basic.

## Wywoływanie usługi

Przed użyciem usługi UnitTest należy załadować lub zaimportować bibliotekę ScriptForge:

• Podstawowe makra wymagają załadowania biblioteki ScriptForge przy użyciu następującej instrukcji:
GlobalScope.BasicLibraries.loadLibrary("ScriptForge")
• Skrypty Pythona wymagają importu z modułu scriptforge:
from scriptforge import CreateScriptService

### Tryb prosty

Wywołaj usługę w trybie prostym, aby wywołać funkcje AssertX bez konieczności budowania pełnej hierarchii zestawów testów i przypadków testowych.

W trybie prostym usługa jest wywoływana wewnątrz przypadku testowego, jak pokazano w poniższym przykładzie:

        Sub SimpleTest
            On Local Error GoTo CatchError
            Dim myTest As Variant
            myTest = CreateScriptService("UnitTest")
            ' Kilka próbnych testów
            myTest.AssertEqual(1 + 1, 2)
            myTest.AssertEqual(1 - 1, 0)
            MsgBox("Wszystkie testy zaliczone")
            Exit Sub
        CatchError:
            myTest.ReportError("Test się nie powiódł")
        End Sub

W tym przykładzie, jeśli którekolwiek z wywołań AssertEqual nie powiedzie się, interpreter przejdzie do etykiety CatchError i zgłosi błąd wywołując metodę ReportError.

### Tryb pełny

Po wywołaniu w trybie pełnym tworzenie usługi odbywa się na zewnątrz kodu testowego, a wszystkie testy są zorganizowane w przypadki testowe i zestawy testów w jednej bibliotece.

Poniższy przykład tworzy instancję UnitTest, której testy znajdują się w bieżącym dokumencie (ThisComponent) w bibliotece "Tests".

        GlobalScope.BasicLibraries.loadLibrary("ScriptForge")
        Dim myUnitTest As Variant
        myUnitTest = CreateScriptService("UnitTest", ThisComponent, "Tests")

### Minimalistyczny przykład w trybie pełnym

Należy wziąć pod uwagę, że plik ODS ma moduł o nazwie "MathUtils" w swojej bibliotece "Standard" z następującym kodem:

        ' Kod w module Standard.MathUtils
        Function Sum(a, b) As Double
            Sum = a + b
        End Function

        Function Multiply(a, b) As Double
            Multiply = a * b
        End Function

Aby utworzyć pełny zestaw testowy, należy wziąć pod uwagę, że w pliku zostanie utworzona nowa biblioteka o nazwie "Tests" z pojedynczym modułem "AllTests" zawierającym poniższy kod:

        ' Kod w module Tests.AllTests
        Sub Main()
            GlobalScope.BasicLibraries.loadLibrary("ScriptForge")
            Dim test As Variant
            test = CreateScriptService("UnitTest", ThisComponent, "Tests")
            test.RunTest("AllTests")
            test.Dispose()
        End Sub

        Sub Setup(test)
            ' Kod przygotowawczy działał przed pierwszym przypadkiem testowym
            Dim exc As Variant
            exc = CreateScriptService("Exception")
            exc.Console(Modal := False)
        End Sub

        Sub TearDown(test)
            ' Opcjonalny kod czyszczący wywoływany po ostatnim przypadku testowym
        End Sub

        Sub Test_Sum(test)
            On Local Error GoTo CatchError
            test.AssertEqual(Sum(1, 1), 2, "Suma dwóch dodatnich liczb całkowitych")
            test.AssertEqual(Sum(-10, 20), 10, "Suma ujemnej i dodatniej liczby całkowitej")
            test.AssertEqual(Sum(1.5, 1), 2.5, "Suma wartości zmiennoprzecinkowych i całkowitych")
            Exit Sub
        CatchError:
            test.ReportError("Metoda sumowania nie działa")
        End Sub

        Sub Test_Multiply(test)
            On Local Error GoTo CatchError
            test.AssertEqual(Multiply(2, 2), 4, "Mnożenie dwóch dodatnich liczb całkowitych")
            test.AssertEqual(Multiply(-4, 2), -8, "Mnożenie liczb całkowitych ujemnych i dodatnich")
            test.AssertEqual(Multiply(1.5, 3), 4.5, "Mnożenie wartości zmiennoprzecinkowych i całkowitych")
            Exit Sub
        CatchError:
            test.ReportError("Metoda mnożenia jest nie działa")
        End Sub

Powyższy zestaw testów składa się z dwóch przypadków testowych Test_Sum i Test_Multiply. Aby uruchomić wszystkie testy, wystarczy uruchomić metodę Main z modułu "AllTests".

Console z usługi Exception służy jako domyślne wyjście dla wyniki testu. Po uruchomieniu powyższego przykładu w konsoli zostaną wyświetlone następujące dane wyjściowe:

        ' RUNTEST ENTER testsuite='Tests.AllTests', pattern='Test_*'
        '   SETUP Tests.AllTests.Setup() ENTER
        '   SETUP Tests.AllTests.Setup() EXIT
        '   TESTCASE Tests.AllTests.Test_Multiply() ENTER
        '   TESTCASE Tests.AllTests.Test_Multiply() EXIT (0,017 sec)
        '   TESTCASE Tests.AllTests.Test_Sum() ENTER
        '   TESTCASE Tests.AllTests.Test_Sum() EXIT (0,016 sec)
        '   TEARDOWN Tests.AllTests.TearDown() ENTER
        '   TEARDOWN Tests.AllTests.TearDown() EXIT
        ' RUNTEST EXIT testsuite='Tests.AllTests' (0,223 sec)

Jeśli którakolwiek z metod AssertEqual nie powiedzie się podczas tych testów, do konsoli zostanie dodany komunikat o błędzie.

## Właściwości

Nazwa | Tylko do odczytu | Typ | Opis
--- | --- | --- | ---
LongMessage | Nie | Boolean | Po ustawieniu wartości True (domyślnie) konsola wyświetli standardowy komunikat dołączony do komunikatu dostarczonego przez testera. Gdy False, używany jest tylko komunikat zdefiniowany przez testera.
ReturnCode | Tak | Integer | Wartość zwrócona przez RunTest po zakończeniu testu jednostkowego. Następna jest lista możliwych wartości: 0 – Test zakończył się bez błędów lub nie został jeszcze uruchomiony. 1 – Niektóre twierdzenie w przypadku testowym zwróciło wartość False. 2 – Przez Setup lub w jakimś przypadku testowym wywołano metodę SkipTest. 3 – Nieprawidłowe zakończenie testu.
Verbose | Nie | Boolean | Jeśli jest ustawione na True, wszystkie twierdzenia są raportowane w konsoli (nieudane lub nie). Gdy False (domyślnie), zgłaszane są tylko nieudane twierdzenia.

WhenAssertionFails

Nie

Integer

Określa, co zostanie zrobione, gdy twierdzenie zakończy się niepowodzeniem. Następna jest lista możliwych wartości:

0 – Awaria jest ignorowana, a przebieg testu jest kontynuowany.
1 – Metoda TearDown z modułu jest wywoływana w bieżącym zestawie testów i uruchamiany jest następny zestaw (domyślnie w trybie pełnym).
2 – Zatrzymaj natychmiast (domyślnie w trybie prostym).

Lista metod w usłudze UnitTest
AssertAlmostEqual AssertEqual AssertFalse AssertGreater AssertGreaterEqual AssertIn AssertIsInstance AssertIsNothing AssertLike | AssertNotRegex AssertIsNull AssertLess AssertLessEqual AssertNotAlmostEqual AssertNotEqual AssertNotIn AssertNotInstance AssertNotLike | AssertNotNothing AssertNotNull AssertRegex AssertTrue Fail Log ReportError RunTest SkipTest

## Argumenty metod AssertX

Wszystkie twierdzenia testują jedno lub dwa wyrażenia, określane w dalszej części tej strony pomocy jako A i B. Są one zawsze pierwszym lub dwoma argumentami metody AssertX.

Wszystkie metody AssertX akceptują argument message określający niestandardowy komunikat, który ma być raportowany w konsoli w związku z twierdzeniem. Domyślnie używany jest pusty ciąg. Argument ten znajduje się zawsze na ostatniej pozycji twierdzenia.

Niektóre metody AssertX akceptują także dodatkowe argumenty, zgodnie z ich składnią poniżej.

## AssertAlmostEqual

Zwraca wartość True, gdy A i B są wartościami liczbowymi i uważa się je za bliskie sobie, biorąc pod uwagę względną tolerancję.

### Składnia:

svc.AssertAlmostEqual(a: any, b: any, tolerance: double = 1E-09, message: str = ""): bool

To twierdzenie zwraca wartość True, jeśli spełnione są dwa poniższe warunki:

- A i B można przekonwertować na typ Double.

- Bezwzględna różnica między A i B podzielona przez największą wartość bezwzględną A lub B jest mniejsza niż wartość określona w tolerance.

## AssertEqual

Zwraca True, gdy A i B są uważane za równe.

### Składnia:

svc.AssertEqual(a: any, b: any, message: str = ""): bool

Gdy A i B są skalarami, zwracana jest wartość True, jeśli:

- Obydwa wyrażenia mają ten sam VarType lub oba są numeryczne.

- Wartości logiczne i numeryczne są porównywane za pomocą operatora =.

- Łańcuchy są porównywane za pomocą wbudowanej funkcji StrComp. W porównaniu rozróżniana jest wielkość liter.

- Daty i godziny są porównywane co do sekundy.

- Null, Empty i Nothing nie są równe, ale AssertEqual(Nothing, Nothing) zwraca wartość True.

- Obiekty UNO są porównywane za pomocą wbudowanej metody EqualUnoObjects.

- Należy pamiętać, że obiekty Basic nigdy nie są równe.

Gdy A i B są tablicami, zwracana jest wartość True, jeśli:

- Obie tablice mają taką samą liczbę wymiarów (maksymalnie 2 wymiary), a ich dolna i górna granica są identyczne dla wszystkich wymiarów.

- Wszystkie elementy w obu tablicach są równe, jeden po drugim.

- Dwie puste tablice są uważane za równe.

## AssertFalse

Zwraca wartość True, jeśli typ A to Boolean, a jego wartość to False.

### Składnia:

svc.AssertFalse(a: any, message: str = ""): bool

## AssertGreater

Zwraca wartość True, gdy A jest większe niż B.

### Składnia:

svc.AssertGreater(a: any, b: any, message: str = ""): bool

Porównanie A i B zakłada, co następuje:

- Dopuszczalne typy danych to String, Date lub numeryczne.

- Obydwa wyrażenia muszą mieć ten sam VarType lub oba muszą być numeryczne.

- W porównaniach ciągów rozróżniana jest wielkość liter.

## AssertGreaterEqual

Zwraca True, gdy A jest większe lub równe B.

### Składnia:

svc.AssertGreaterEqual(a: any, b: any, message: str = ""): bool

Porównanie A i B zakłada, co następuje:

- Dopuszczalne typy danych to String, Date lub numeryczne.

- Obydwa wyrażenia muszą mieć ten sam VarType lub oba muszą być numeryczne.

- W porównaniach ciągów rozróżniana jest wielkość liter.

## AssertIn

Zwraca wartość True, gdy A znajduje się w B.

### Składnia:

svc.AssertIn(a: any, b: any, message: str = ""): bool

Twierdzenie to zakłada, co następuje:

- Wyrażenie B może być tablicą 1D, obiektem Dictionary ScriptForge lub ciągiem znaków.

- Gdy wyrażenie B jest tablicą 1D, wyrażenie A może być datą lub wartością liczbową.

- Gdy wyrażenie B jest obiektem Dictionary ScriptForge, wówczas wśród kluczy w B wyszukiwany jest ciąg A.

- W porównaniach ciągów rozróżniana jest wielkość liter.

## AssertIsInstance

Zwraca True, gdy A jest instancją określonego typu obiektu, określonego jako ciąg znaków zawierający nazwę typu.

### Składnia:

svc.AssertIsInstance(a: any, objecttype: str, message: str = ""): bool

Wyrażenie A może mieć jedną z następujących postaci:

- Obiekt ScriptForge. W tym przypadku argumentem objecttype jest ciąg znaków, taki jak "DICTIONARY", "calc", "Dialog" itp.

- Obiekt UNO. W tym przypadku argument objecttype musi być ciągiem znaków identycznym z wartością zwróconą przez metodę SF_Session.UnoObjectType().

- Tablica. W tym przypadku oczekuje się, że argumentem objecttype będzie "tablica".

- Dowolna inna zmienna (ani Object, ani Array). W tym przypadku objecttype jest ciągiem znaków pasującym do wartości zwróconej przez wbudowaną funkcję TypeName.

## AssertIsNothing

Zwraca wartość True, gdy A jest obiektem mającym wartość Nothing.

### Składnia:

svc.AssertIsNothing(a: any, message: str = ""): bool

## AssertIsNull

Zwraca True, gdy A ma wartość Null.

### Składnia:

svc.AssertIsNull(a: any, message: str = ""): bool

## AssertLess

Zwraca wartość True, gdy A jest mniejsze niż B.

### Składnia:

svc.AssertLess(a: any, b: any, message: str = ""): bool

Porównanie A i B zakłada, co następuje:

- Dopuszczalne typy danych to String, Date lub numeryczne.

- Obydwa wyrażenia muszą mieć ten sam VarType lub oba muszą być numeryczne.

- W porównaniach ciągów rozróżniana jest wielkość liter.

## AssertLessEqual

Zwraca wartość True, gdy A jest mniejsze lub równe B.

### Składnia:

svc.AssertLessEqual(a: any, b: any, message: str = ""): bool

Porównanie A i B zakłada, co następuje:

- Dopuszczalne typy danych to String, Date lub numeryczne.

- Obydwa wyrażenia muszą mieć ten sam VarType lub oba muszą być numeryczne.

- W porównaniach ciągów rozróżniana jest wielkość liter.

## AssertLike

Zwraca wartość True, jeśli ciąg A pasuje do podanego wzorca zawierającego symbole wieloznaczne.

### Składnia:

svc.AssertLike(a: any, pattern: str = "", message: str = ""): bool

Akceptowane są następujące symbole wieloznaczne:

- ? – reprezentuje dowolny pojedynczy znak.

- * – reprezentuje zero, jeden lub wiele znaków.

## AssertNotAlmostEqual

Zwraca True, jeśli A i B są wartościami liczbowymi i nie są uważane za bliskie z określoną tolerancją względną.

### Składnia:

svc.AssertNotAlmostEqual(a: any, b: any, tolerance: double = 1E-09, message: str = ""): bool

To twierdzenie zwraca wartość True, jeśli spełnione są dwa poniższe warunki:

- A i B można przekonwertować na typ Double.

- Bezwzględna różnica między A i B podzielona przez największą wartość bezwzględną A lub B jest większa niż wartość określona w tolerance.

## AssertNotEqual

Zwraca True, gdy A i B nie są uważane za równe.

### Składnia:

svc.AssertNotEqual(a: any, b: any, message: str = ""): bool

Ta metoda działa zarówno w przypadku skalarów, jak i tablic. Przeczytaj instrukcje w AssertEqual, aby uzyskać więcej informacji na temat znaczenia równości w tym twierdzeniu.

## AssertNotIn

Zwraca wartość True, gdy A (ciąg znaków) nie występuje w B.

### Składnia:

svc.AssertNotIn(a: any, b: any, message: str = ""): bool

Przeczytaj instrukcję w AssertIn, aby uzyskać więcej informacji na temat założeń tej metody.

## AssertNotInstance

Zwraca True, gdy A nie jest instancją określonego typu obiektu.

### Składnia:

svc.AssertNotInstance(a: any, objecttype: str, message: str = ""): bool

Przeczytaj instrukcję w AssertIsInstance, aby uzyskać więcej informacji na temat twierdzeń tej metody.

## AssertNotLike

Zwraca True, jeśli ciąg A nie pasuje do podanego wzorca zawierającego symbole wieloznaczne.

### Składnia:

svc.AssertNotLike(a: any, pattern: str = "", message: str = ""): bool

Przeczytaj instrukcję w AssertLike, aby uzyskać więcej informacji na temat twierdzeń tej metody.

## AssertNotNothing

Zwraca True, chyba że A jest obiektem mającym wartość Nothing.

### Składnia:

svc.AssertNotNothing(a: any, message: str = ""): bool

## AssertNotNull

Zwraca True, chyba że A ma wartość Null.

### Składnia:

svc.AssertNotNull(a: any, message: str = ""): bool

## AssertNotRegex

Zwraca True, gdy A jest nie ciągiem znaków lub nie pasuje do podanego wyrażenia regularnego.

### Składnia:

svc.AssertNotRegex(a: any, regex: str = "", message: str = ""): bool

W porównaniu rozróżniana jest wielkość liter.

## AssertRegex

Zwraca True, gdy ciąg A pasuje do podanego wyrażenia regularnego.

### Składnia:

svc.AssertRegex(a: any, regex: str = "", message: str = ""): bool

W porównaniu rozróżniana jest wielkość liter.

## AssertTrue

Zwraca True, gdy wyrażenie A jest Boolean i jego wartość to True.

### Składnia:

svc.AssertTrue(a: any, message: str = ""): bool

## Fail

Wymusza niepowodzenie przypadku testowego.

### Składnia:

svc.Fail(message: str = "")

Można podać komunikat, który zostanie zgłoszony w konsoli.

## Log

Zapisuje określony message w konsoli.

### Składnia:

svc.Log(message: str = "")

Można podać komunikat, który zostanie zgłoszony w konsoli.

## ReportError

Wyświetla okno komunikatu z komunikatem i bieżącymi wartościami właściwości usługi Exception.

Ta metoda jest powszechnie używana w sekcji obsługi wyjątków Sub zawierającej przypadek testowy, który jest osiągany, gdy twierdzenie się nie powiedzie lub gdy zostanie wywołana metoda Fail.

### Składnia:

svc.ReportError(message: str = "")

W zależności od wartości właściwości WhenAssertionFails wykonywanie testu może być kontynuowane lub przerwane.

Podczas pisania przypadków testowych zaleca się uwzględnienie wywołania metody ReportError w sekcji obsługi wyjątków Sub.

Jeśli właściwość LongMessage jest równa True, po określonym message następuje standardowy opis komunikatu o błędzie. W przeciwnym razie wyświetlany jest tylko message.

## RunTest

Wykonuje kompletny zestaw testów zaimplementowany w określonym module. Każdy przypadek testowy jest uruchamiany niezależnie od siebie.

Uruchamianie zestawu testów obejmuje:

1. Wykonywanie opcjonalnej metody Setup obecnej w module.

2. Wykonywanie raz każdego przypadku testowego, w dowolnej kolejności.

3. Wykonanie opcjonalnej metody TearDown obecnej w module.

### Składnia:

svc.RunTest(testsuite: str, testcasepattern: str = "", message: str = ""): int

Argument testcasepattern określa wzorzec złożony z symboli wieloznacznych "?" i "*", aby wybrać przypadki testowe, które zostaną uruchomione. W porównaniu nie jest rozróżniana wielkość liter.

Jeśli zostanie podany message, zostanie on zapisany w konsoli po rozpoczęciu testu.

## SkipTest

Przerywa działający zestaw testów bez wywoływania metody TearDown.

Pominięcie testu ma zwykle sens podczas stosowania metody Setup, gdy nie wszystkie warunki uruchomienia testu są spełnione.

Do metody Setup należy wyjście z Sub wkrótce po wywołaniu SkipTest.

Jeśli SkipTest zostanie wywołany z poziomu przypadku testowego, wykonywanie zestawu testów zostanie przerwane, a pozostałe przypadki testowe nie zostaną uruchomione. Należy pamiętać, że kolejność uruchamiania przypadków testowych jest dowolna w ramach zestawu testów.

### Składnia:

svc.SkipTest(message: str = "")

Jeśli zostanie podany message, zostanie on zapisany w konsoli.

Tematy pokrewne

Usługa ScriptForge.Exception