Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym przewodniku utworzysz test jednostkowy programu SQL Server, który weryfikuje zachowanie kilku procedur składowanych. Utworzysz testy jednostkowe programu SQL Server, aby zidentyfikować wady kodu, które mogą powodować nieprawidłowe zachowanie aplikacji. Testy jednostkowe i testy aplikacji programu SQL Server można uruchamiać w ramach zautomatyzowanego zestawu testów.
W tym przewodniku wykonasz następujące zadania:
- Tworzenie skryptu zawierającego schemat bazy danych
- Tworzenie projektu bazy danych i importowanie tego schematu
- Wdrażanie projektu bazy danych w izolowanym środowisku projektowym
- Tworzenie testów jednostkowych programu SQL Server
- Definiowanie logiki testowej
- Uruchamianie testów jednostkowych programu SQL Server
- Dodawanie ujemnego testu jednostkowego
Gdy jeden z testów jednostkowych wykryje błąd w procedurze składowanej, należy poprawić ten błąd i ponownie uruchomić test.
Wymagania wstępne
Aby ukończyć ten przewodnik, musisz mieć możliwość nawiązania połączenia z serwerem bazy danych (lub bazą danych LocalDB), na którym masz uprawnienia do tworzenia i wdrażania bazy danych. Aby uzyskać więcej informacji, zobacz Wymagane uprawnienia dla funkcji bazy danych programu Visual Studio.
Tworzenie skryptu zawierającego schemat bazy danych
W menu Plik wskaż pozycję Nowy, a następnie wybierz pozycję Plik.
Zostanie wyświetlone okno dialogowe Nowy plik .
Na liście Kategorie wybierz pozycję Ogólne , jeśli nie został jeszcze wyróżniony.
Na liście Szablony wybierz pozycję Plik SQL, a następnie wybierz pozycję Otwórz.
Zostanie otwarty edytor Transact-SQL.
Skopiuj poniższy kod Transact-SQL i wklej go do edytora Transact-SQL.
PRINT N'Creating Sales...'; GO CREATE SCHEMA [Sales] AUTHORIZATION [dbo]; GO PRINT N'Creating Sales.Customer...'; GO CREATE TABLE [Sales].[Customer] ( [CustomerID] INT IDENTITY (1, 1) NOT NULL, [CustomerName] NVARCHAR (40) NOT NULL, [YTDOrders] INT NOT NULL, [YTDSales] INT NOT NULL ); GO PRINT N'Creating Sales.Orders...'; GO CREATE TABLE [Sales].[Orders] ( [CustomerID] INT NOT NULL, [OrderID] INT IDENTITY (1, 1) NOT NULL, [OrderDate] DATETIME NOT NULL, [FilledDate] DATETIME NULL, [Status] CHAR (1) NOT NULL, [Amount] INT NOT NULL ); GO PRINT N'Creating Sales.Def_Customer_YTDOrders...'; GO ALTER TABLE [Sales].[Customer] ADD CONSTRAINT [Def_Customer_YTDOrders] DEFAULT 0 FOR [YTDOrders]; GO PRINT N'Creating Sales.Def_Customer_YTDSales...'; GO ALTER TABLE [Sales].[Customer] ADD CONSTRAINT [Def_Customer_YTDSales] DEFAULT 0 FOR [YTDSales]; GO PRINT N'Creating Sales.Def_Orders_OrderDate...'; GO ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [Def_Orders_OrderDate] DEFAULT GetDate() FOR [OrderDate]; GO PRINT N'Creating Sales.Def_Orders_Status...'; GO ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [Def_Orders_Status] DEFAULT 'O' FOR [Status]; GO PRINT N'Creating Sales.PK_Customer_CustID...'; GO ALTER TABLE [Sales].[Customer] ADD CONSTRAINT [PK_Customer_CustID] PRIMARY KEY CLUSTERED ([CustomerID] ASC) WITH (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON, PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF); GO PRINT N'Creating Sales.PK_Orders_OrderID...'; GO ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [PK_Orders_OrderID] PRIMARY KEY CLUSTERED ([OrderID] ASC) WITH (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON, PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF); GO PRINT N'Creating Sales.FK_Orders_Customer_CustID...'; GO ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [FK_Orders_Customer_CustID] FOREIGN KEY ([CustomerID]) REFERENCES [Sales].[Customer] ([CustomerID]) ON DELETE NO ACTION ON UPDATE NO ACTION; GO PRINT N'Creating Sales.CK_Orders_FilledDate...'; GO ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [CK_Orders_FilledDate] CHECK ((FilledDate >= OrderDate) AND (FilledDate < '01/01/2030')); GO PRINT N'Creating Sales.CK_Orders_OrderDate...'; GO ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [CK_Orders_OrderDate] CHECK ((OrderDate > '01/01/2005') AND (OrderDate < '01/01/2030')); GO PRINT N'Creating Sales.uspCancelOrder...'; GO CREATE PROCEDURE [Sales].[uspCancelOrder] @OrderID INT AS BEGIN DECLARE @Delta AS INT, @CustomerID AS INT; BEGIN TRANSACTION; SELECT @Delta = [Amount], @CustomerID = [CustomerID] FROM [Sales].[Orders] WHERE [OrderID] = @OrderID; UPDATE [Sales].[Orders] SET [Status] = 'X' WHERE [OrderID] = @OrderID; UPDATE [Sales].[Customer] SET YTDOrders = YTDOrders - @Delta WHERE [CustomerID] = @CustomerID; COMMIT TRANSACTION; END GO PRINT N'Creating Sales.uspFillOrder...'; GO CREATE PROCEDURE [Sales].[uspFillOrder] @OrderID INT, @FilledDate DATETIME AS BEGIN DECLARE @Delta AS INT, @CustomerID AS INT; BEGIN TRANSACTION; SELECT @Delta = [Amount], @CustomerID = [CustomerID] FROM [Sales].[Orders] WHERE [OrderID] = @OrderID; UPDATE [Sales].[Orders] SET [Status] = 'F', [FilledDate] = @FilledDate WHERE [OrderID] = @OrderID; UPDATE [Sales].[Customer] SET YTDSales = YTDSales - @Delta WHERE [CustomerID] = @CustomerID; COMMIT TRANSACTION; END GO PRINT N'Creating Sales.uspNewCustomer...'; GO CREATE PROCEDURE [Sales].[uspNewCustomer] @CustomerName NVARCHAR (40) AS BEGIN INSERT INTO [Sales].[Customer] (CustomerName) VALUES (@CustomerName); RETURN SCOPE_IDENTITY(); END GO PRINT N'Creating Sales.uspPlaceNewOrder...'; GO CREATE PROCEDURE [Sales].[uspPlaceNewOrder] @CustomerID INT, @Amount INT, @OrderDate DATETIME, @Status CHAR (1)='O' AS BEGIN DECLARE @RC AS INT; BEGIN TRANSACTION; INSERT INTO [Sales].[Orders] (CustomerID, OrderDate, FilledDate, Status, Amount) VALUES (@CustomerID, @OrderDate, NULL, @Status, @Amount); SELECT @RC = SCOPE_IDENTITY(); UPDATE [Sales].[Customer] SET YTDOrders = YTDOrders + @Amount WHERE [CustomerID] = @CustomerID; COMMIT TRANSACTION; RETURN @RC; END GO CREATE PROCEDURE [Sales].[uspShowOrderDetails] @CustomerID INT=0 AS BEGIN SELECT [C].[CustomerName], CONVERT (DATE, [O].[OrderDate]), CONVERT (DATE, [O].[FilledDate]), [O].[Status], [O].[Amount] FROM [Sales].[Customer] AS C INNER JOIN [Sales].[Orders] AS O ON [O].[CustomerID] = [C].[CustomerID] WHERE [C].[CustomerID] = @CustomerID; END GOZapisz plik. Zanotuj lokalizację, ponieważ należy użyć tego skryptu w następnej procedurze.
W menu Plik wybierz pozycję Zamknij rozwiązanie.
Następnie utworzysz projekt bazy danych i zaimportujesz schemat z utworzonego skryptu.
Tworzenie projektu bazy danych i importowanie schematu
Tworzenie projektu bazy danych
W menu Plik wskaż pozycję Nowy, a następnie wybierz pozycję Projekt.
Zostanie wyświetlone okno dialogowe Nowy projekt .
W obszarze Zainstalowane szablony wybierz węzeł SQL Server , a następnie wybierz pozycję Projekt bazy danych programu SQL Server.
W polu Nazwa wpisz
SimpleUnitTestDB.Zaznacz pole wyboru Utwórz katalog dla rozwiązania , jeśli nie jest jeszcze zaznaczone.
Wyczyść pole wyboru Dodaj do kontroli źródła , jeśli nie jest jeszcze wyczyszczone, a następnie wybierz przycisk OK.
Projekt bazy danych jest tworzony i wyświetlany w Eksploratorze rozwiązań. Następnie zaimportujesz schemat bazy danych ze skryptu.
Importowanie schematu bazy danych ze skryptu
W menu Projekt wybierz pozycję Importuj , a następnie pozycję Skrypt (*.sql).
Po przeczytaniu strony powitalnej wybierz pozycję Dalej .
Wybierz pozycję Przeglądaj i przejdź do katalogu, w którym zapisano
.sqlplik..sqlKliknij dwukrotnie plik, a następnie wybierz pozycję Zakończ.Skrypt jest importowany, a obiekty zdefiniowane w tym skry skrygcie są dodawane do projektu bazy danych.
Przejrzyj podsumowanie, a następnie wybierz pozycję Zakończ , aby ukończyć operację.
Uwaga / Notatka
Procedura Sales.uspFillOrder zawiera zamierzony błąd kodowania, który zostanie wykryty i poprawiony w dalszej części tej procedury.
Przeanalizuj końcowy projekt
W Eksploratorze rozwiązań sprawdź pliki skryptów zaimportowane do projektu.
W Eksploratorze obiektów programu SQL Server przyjrzyj się bazie danych w węźle Projekty.
Wdrażanie w bazie danych LocalDB
Domyślnie po naciśnięciu F5 należy wdrożyć (lub opublikować) bazę danych w bazie danych LocalDB. Lokalizację bazy danych można zmienić, przechodząc do karty Debugowanie strony właściwości projektu i zmieniając parametry połączenia.
Tworzenie testów jednostkowych programu SQL Server
Tworzenie testu jednostkowego programu SQL Server dla procedur składowanych
W Eksploratorze obiektów programu SQL Server rozwiń węzeł projektów
SimpleUnitTestDB, a następnie węzeł Programowalność, a potem węzeł Procedury składowane.Kliknij prawym przyciskiem myszy jedną z procedur składowanych i wybierz polecenie Utwórz testy jednostkowe , aby wyświetlić okno dialogowe Tworzenie testów jednostkowych .
Zaznacz pola wyboru dla wszystkich pięciu procedur składowanych: Sales.uspCancelOrder, Sales.uspFillOrder, Sales.uspNewCustomer, Sales.uspPlaceNewOrder i Sales.uspShowOrderDetails.
Z listy rozwijanej Project (Projekt ) wybierz pozycję Create a new C# test project (Utwórz nowy projekt testowy języka C#).
Zaakceptuj nazwy domyślne nazwy projektu i nazwy klasy, a następnie wybierz przycisk OK.
W oknie dialogowym Konfiguracja testu w obszarze Wykonywanie testów jednostkowych przy użyciu następującego połączenia danych określ połączenie z bazą danych, która została wdrożona wcześniej w tym przewodniku. Jeśli na przykład użyto domyślnej lokalizacji wdrożenia, czyli lokalnej bazy danychDB, wybierz pozycję Nowe połączenie określ (LocalDB)\Projects. Następnie wybierz nazwę bazy danych. Następnie wybierz przycisk OK , aby zamknąć okno dialogowe Właściwości połączenia .
Uwaga / Notatka
Jeśli musisz przetestować widoki lub procedury składowane z ograniczonymi uprawnieniami, zazwyczaj należy określić to połączenie w tym kroku. Następnie należy określić połączenie pomocnicze z szerszymi uprawnieniami, aby zweryfikować test. Jeśli masz połączenie pomocnicze, należy dodać tego użytkownika do projektu bazy danych i utworzyć identyfikator logowania dla tego użytkownika w skrycie wdrażania wstępnego.
W oknie dialogowym konfiguracja testu w sekcji Wdrażanie zaznacz pole wyboru Automatycznie wdróż projekt bazy danych przed uruchomieniem testów jednostkowych .
W obszarze Projekt bazy danych wybierz pozycję
SimpleUnitTestDB.sqlproj.W obszarze Konfiguracja wdrożenia wybierz pozycję Debuguj.
Możesz również wygenerować dane testowe w ramach testów jednostkowych programu SQL Server. W tym przewodniku pominiesz ten krok, ponieważ testy tworzą własne dane.
Kliknij przycisk OK.
Uruchamia się projekt testowy i pojawia się Projektant testów jednostkowych programu SQL Server. Następnie zaktualizujesz logikę testu w skrypcie Transact-SQL testów jednostkowych.
Definiowanie logiki testowej
Ta podstawowa baza danych ma dwie tabele, Customer i Order. Aktualizujesz bazę danych, używając następujących procedur składowanych:
| procedura składowana | Description |
|---|---|
uspNewCustomer |
Ta procedura składowana dodaje rekord do tabeli Customer, który ustawia kolumny YTDOrders i YTDSales klienta na zero. |
uspPlaceNewOrder |
Ta procedura składowana dodaje rekord do tabeli Orders dla określonego klienta i aktualizuje wartość YTDOrders w odpowiednim rekordzie tabeli Customer. |
uspFillOrder |
Ta procedura składowana aktualizuje rekord w tabeli Orders, zmieniając stan z "O" na "F" i zwiększa kwotę w odpowiednim rekordzie w tabeli YTDSales. |
uspCancelOrder |
Ta procedura składowana aktualizuje rekord w tabeli Orders, zmieniając stan z "O" na "X" i dekrementując kwotę YTDOrders dla odpowiedniego rekordu w tabeli Customer. |
uspShowOrderDetails |
Ta procedura przechowywana łączy tabelę Orders z tabelą Custom i pokazuje rekordy dla określonego klienta. |
Uwaga / Notatka
W tym przykładzie pokazano, jak utworzyć podstawowy test jednostkowy programu SQL Server. W rzeczywistej bazie danych można zsumować łączne kwoty wszystkich zamówień ze stanem "O" lub "F" dla określonego klienta. Procedury opisane w tym przewodniku również nie zawierają obsługi błędów. Na przykład nie uniemożliwiają wywołania funkcji uspFillOrder dotyczącej zamówienia, które zostało już zrealizowane.
Testy zakładają, że baza danych jest uruchamiana w stanie czystego. Utworzysz testy, które weryfikują następujące warunki:
uspNewCustomer: Sprawdź, czy tabelaCustomerzawiera jeden wiersz po uruchomieniu procedury składowanej.uspPlaceNewOrder: Dla klienta, który maCustomerIDwartość 1, należy złożyć zamówienie na 100 USD. Sprawdź, czyYTDOrderskwota dla klienta wynosi 100, aYTDSaleskwota wynosi zero.uspFillOrder: Dla klienta, który maCustomerIDwartość 1, należy złożyć zamówienie na 50 USD. Wypełnij to zamówienie. Sprawdź, czy kwotyYTDOrdersiYTDSalessą równe 50.uspShowOrderDetails: Dla klienta, który maCustomerIDwartość 1, należy złożyć zamówienia za 100 USD, 50 USD i 5 USD. Sprawdź, czyuspShowOrderDetailszwraca prawidłową liczbę kolumn i czy zestaw wyników ma oczekiwaną sumę kontrolną.
Uwaga / Notatka
W przypadku kompletnego zestawu testów jednostkowych programu SQL Server zwykle sprawdza się, czy inne kolumny zostały ustawione poprawnie. Aby utrzymać rozmiar tego przewodnika w rozsądnych granicach, nie opisano w nim, jak zweryfikować działanie uspCancelOrder.
Napisz jednostkowy test dla SQL Server uspNewCustomer
Na pasku nawigacyjnym projektanta testów jednostkowych programu SQL Server wybierz pozycję Sales_uspNewCustomerTest i upewnij się, że test został wyróżniony na sąsiedniej liście.
Po wykonaniu poprzedniego kroku możesz utworzyć skrypt testowy dla akcji testowej w teście jednostkowym.
Zaktualizuj instrukcje Transact-SQL w edytorze Transact-SQL, aby odpowiadały następującym instrukcjom:
-- ssNoVersion unit test for Sales.uspNewCustomer DECLARE @RC AS INT, @CustomerName AS NVARCHAR (40); SELECT @RC = 0, @CustomerName = 'Fictitious Customer'; EXECUTE @RC = [Sales].[uspNewCustomer] @CustomerName; SELECT * FROM [Sales].[Customer];W okienku Warunki testu wybierz niejednoznaczny warunek testu, a następnie wybierz ikonę Usuń warunek testu (czerwony X).
W okienku Warunki testu wybierz pozycję Liczba wierszy na liście, a następnie wybierz ikonę Dodaj warunek testu (zielony +).
Otwórz okno Właściwości (wybierz warunek testu i naciśnij F4), a następnie ustaw właściwość Liczba wierszy na 1.
W menu Plik wybierz pozycję Zapisz wszystko.
Następnie zdefiniuj logikę testu jednostkowego dla elementu
uspPlaceNewOrder.
Napisz test jednostkowy SQL Server dla uspPlaceNewOrder
Na pasku nawigacyjnym Projektanta Testów Jednostkowych programu SQL Server wybierz Sales_uspPlaceNewOrderTest i upewnij się, że Test jest zaznaczony na sąsiedniej liście.
Po wykonaniu tego kroku możesz utworzyć skrypt testowy dla akcji testowej w teście jednostkowym.
Zaktualizuj instrukcje Transact-SQL w edytorze Transact-SQL, aby odpowiadały następującym instrukcjom:
-- ssNoVersion unit test for Sales.uspPlaceNewOrder DECLARE @RC AS INT, @CustomerID AS INT, @Amount AS INT, @OrderDate AS DATETIME, @Status AS CHAR (1); DECLARE @CustomerName AS NVARCHAR (40); -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script. SELECT @RC = 0, @CustomerID = 0, @CustomerName = N'Fictitious Customer', @Amount = 100, @OrderDate = getdate(), @Status = 'O'; SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName; -- place an order for that customer EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, @Amount, @OrderDate, @Status; -- verify that the YTDOrders value is correct. SELECT @RC = [YTDOrders] FROM [Sales].[Customer] WHERE [CustomerID] = @CustomerID; SELECT @RC AS RC;W okienku Warunki testu wybierz niejednoznaczny warunek testu, a następnie wybierz pozycję Usuń warunek testu.
W okienku Warunki testu wybierz pozycję Wartość skalarna na liście, a następnie wybierz pozycję Dodaj warunek testu.
W oknie Właściwości ustaw właściwość Oczekiwana wartość na 100.
Na pasku nawigacyjnym projektanta testów jednostkowych programu SQL Server wybierz pozycję Sales_uspPlaceNewOrderTest i upewnij się, że na sąsiedniej liście wyróżniono pozycję Pre-Test .
Po wykonaniu tego kroku można określić instrukcje, które umieszczają dane w stanie wymaganym do wykonania testu. Aby można było złożyć zamówienie, w tym przykładzie należy najpierw utworzyć rekord
Customer.Wybierz Kliknij tutaj, aby utworzyć, aby utworzyć skrypt przedtestowy.
Zaktualizuj instrukcje Transact-SQL w edytorze Transact-SQL, aby odpowiadały następującym instrukcjom:
/* Add Transact-SQL statements here that you want to run before the test script is run. */ -- Add a customer for this test with the name 'Fictitious Customer' DECLARE @NewCustomerID AS INT, @CustomerID AS INT, @RC AS INT, @CustomerName AS NVARCHAR (40); SELECT @RC = 0, @NewCustomerID = 0, @CustomerID = 0, @CustomerName = N'Fictitious Customer'; IF NOT EXISTS (SELECT * FROM [Sales].[Customer] WHERE CustomerName = @CustomerName) BEGIN EXECUTE @NewCustomerID = [Sales].[uspNewCustomer] @CustomerName; END -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script. SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName; -- delete any old records in the Orders table and clear out the YTD Sales/Orders fields DELETE [Sales].[Orders] WHERE [CustomerID] = @CustomerID; UPDATE [Sales].[Customer] SET YTDOrders = 0, YTDSales = 0 WHERE [CustomerID] = @CustomerID;W menu Plik wybierz pozycję Zapisz wszystko.
Następnie utworzysz test jednostkowy dla elementu
uspFillOrder.
Napisz test jednostkowy SQL Server dla uspFillOrder
Na pasku nawigacyjnym projektanta testów jednostkowych programu SQL Server wybierz pozycję Sales_uspFillOrderTest i upewnij się, że test został wyróżniony na sąsiedniej liście.
Po wykonaniu tego kroku możesz utworzyć skrypt testowy dla akcji testowej w teście jednostkowym.
Zaktualizuj instrukcje Transact-SQL w edytorze Transact-SQL, aby odpowiadały następującym instrukcjom:
-- ssNoVersion unit test for Sales.uspFillOrder DECLARE @RC AS INT, @CustomerID AS INT, @Amount AS INT, @FilledDate AS DATETIME, @Status AS CHAR (1); DECLARE @CustomerName AS NVARCHAR (40), @OrderID AS INT; SELECT @RC = 0, @CustomerID = 0, @OrderID = 0, @CustomerName = N'Fictitious Customer', @Amount = 100, @FilledDate = getdate(), @Status = 'O'; -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script. SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName; -- Get the most recently added order. SELECT @OrderID = MAX([OrderID]) FROM [Sales].[Orders] WHERE [CustomerID] = @CustomerID; -- fill an order for that customer EXECUTE @RC = [Sales].[uspFillOrder] @OrderID, @FilledDate; -- verify that the YTDOrders value is correct. SELECT @RC = [YTDSales] FROM [Sales].[Customer] WHERE [CustomerID] = @CustomerID; SELECT @RC AS RC;W okienku Warunki testu wybierz niejednoznaczny warunek testu, a następnie wybierz pozycję Usuń warunek testu.
W okienku Warunki testu wybierz pozycję Wartość skalarna na liście, a następnie wybierz pozycję Dodaj warunek testu.
W oknie Właściwości ustaw właściwość Oczekiwana wartość na 100.
Na pasku nawigacyjnym projektanta testów jednostkowych programu SQL Server wybierz pozycję Sales_uspFillOrderTest i upewnij się, że na sąsiedniej liście wyróżniono pozycję Pre-Test . Po wykonaniu tego kroku można określić instrukcje, które umieszczają dane w stanie wymaganym do wykonania testu. W tym przykładzie należy utworzyć rekord Klienta, aby można było złożyć zamówienie.
Wybierz Kliknij tutaj, aby utworzyć, aby utworzyć skrypt przedtestowy.
Zaktualizuj instrukcje Transact-SQL w edytorze Transact-SQL, aby odpowiadały następującym instrukcjom:
/* Add Transact-SQL statements here that you want to run before the test script is run. */ BEGIN TRANSACTION -- Add a customer for this test with the name 'CustomerB' ; DECLARE @NewCustomerID AS INT, @RC AS INT, @CustomerName AS NVARCHAR (40); SELECT @RC = 0, @NewCustomerID = 0, @CustomerName = N'Fictitious Customer'; IF NOT EXISTS (SELECT * FROM [Sales].[Customer] WHERE CustomerName = @CustomerName) BEGIN EXECUTE @NewCustomerID = [Sales].[uspNewCustomer] @CustomerName; END DECLARE @CustomerID AS INT, @Amount AS INT, @OrderDate AS DATETIME, @Status AS CHAR (1); SELECT @RC = 0, @CustomerID = 0, @CustomerName = N'Fictitious Customer', @Amount = 100, @OrderDate = getdate(), @Status = 'O'; -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script. SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName; -- delete any old records in the Orders table and clear out the YTD Sales/Orders fields DELETE [Sales].[Orders] WHERE [CustomerID] = @CustomerID; UPDATE [Sales].[Customer] SET YTDOrders = 0, YTDSales = 0 WHERE [CustomerID] = @CustomerID; EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, @Amount, @OrderDate, @Status; COMMIT TRANSACTION; -- place an order for that customerW menu Plik wybierz pozycję Zapisz wszystko.
Napisz jednostkowy test SQL Server dla procedury uspShowOrderDetails
Na pasku nawigacyjnym projektanta testów jednostkowych programu SQL Server wybierz pozycję Sales_uspShowOrderDetailsTest i upewnij się, że test został wyróżniony na sąsiedniej liście.
Po wykonaniu tego kroku możesz utworzyć skrypt testowy dla akcji testowej w teście jednostkowym.
Zaktualizuj instrukcje Transact-SQL w edytorze Transact-SQL, aby odpowiadały następującym instrukcjom:
-- ssNoVersion unit test for Sales.uspFillOrder DECLARE @RC AS INT, @CustomerID AS INT, @Amount AS INT, @FilledDate AS DATETIME, @Status AS CHAR (1); DECLARE @CustomerName AS NVARCHAR (40), @OrderID AS INT; SELECT @RC = 0, @CustomerID = 0, @OrderID = 0, @CustomerName = N'Fictitious Customer', @Amount = 100, @FilledDate = getdate(), @Status = 'O'; -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script. SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName; -- fill an order for that customer EXECUTE @RC = [Sales].[uspShowOrderDetails] @CustomerID; SELECT @RC AS RC;W okienku Warunki testu wybierz niejednoznaczny warunek testu, a następnie wybierz pozycję Usuń warunek testu.
W okienku Warunki testu wybierz pozycję Oczekiwany schemat na liście, a następnie wybierz pozycję Dodaj warunek testu.
W oknie Właściwości we właściwości Konfiguracja wybierz przycisk przeglądania ('...').
W oknie dialogowym Konfiguracja dla expectedSchemaCondition1 określ połączenie z bazą danych. Jeśli na przykład użyto domyślnej lokalizacji wdrożenia, czyli lokalnej bazy danychDB, wybierz pozycję Nowe połączenie określ (LocalDB)\Projects. Następnie wybierz nazwę bazy danych.
Wybierz Pobierz. (W razie potrzeby wybierz pozycję Pobierz , dopóki nie zobaczysz danych).
Treść testu jednostkowego napisana w Transact-SQL zostanie wykonana, a wynikowy schemat pojawi się w oknie dialogowym. Ponieważ kod wstępny nie został wykonany, żadne dane nie są zwracane. Ponieważ sprawdzasz tylko schemat, a nie dane, jest to w porządku.
Kliknij przycisk OK.
Oczekiwany schemat jest przechowywany z warunkiem testu.
Na pasku nawigacyjnym projektanta testów jednostkowych programu SQL Server wybierz pozycję Sales_uspShowOrderDetailsTest i upewnij się, że na sąsiedniej liście wyróżniono pozycję Pre-Test . Po wykonaniu tego kroku można określić instrukcje, które umieszczają dane w stanie wymaganym do wykonania testu. Aby można było złożyć zamówienie, w tym przykładzie należy najpierw utworzyć rekord
Customer.Wybierz Kliknij tutaj, aby utworzyć, aby utworzyć skrypt przedtestowy.
Zaktualizuj instrukcje Transact-SQL w edytorze Transact-SQL, aby odpowiadały następującym instrukcjom:
/* Add Transact-SQL statements here to run before the test script is run. */ BEGIN TRANSACTION -- Add a customer for this test with the name 'FictitiousCustomer' ; DECLARE @NewCustomerID AS INT, @RC AS INT, @CustomerName AS NVARCHAR (40); SELECT @RC = 0, @NewCustomerID = 0, @CustomerName = N'Fictitious Customer'; IF NOT EXISTS (SELECT * FROM [Sales].[Customer] WHERE CustomerName = @CustomerName) BEGIN EXECUTE @NewCustomerID = [Sales].[uspNewCustomer] @CustomerName; END DECLARE @CustomerID AS INT, @Amount AS INT, @OrderDate AS DATETIME, @Status AS CHAR (1); SELECT @RC = 0, @CustomerID = 0, @CustomerName = N'Fictitious Customer', @OrderDate = getdate(), @Status = 'O'; -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script. SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName; -- delete any old records in the Orders table and clear out the YTD Sales/Orders fields DELETE [Sales].[Orders] WHERE [CustomerID] = @CustomerID; UPDATE [Sales].[Customer] SET YTDOrders = 0, YTDSales = 0 WHERE [CustomerID] = @CustomerID; EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 100, @OrderDate, @Status; EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 50, @OrderDate, @Status; EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 5, @OrderDate, @Status; COMMIT TRANSACTION; -- place 3 orders for that customerNa pasku nawigacyjnym projektanta testów jednostkowych programu SQL Server wybierz pozycję Sales_uspShowOrderDetailsTest i wybierz pozycję Testuj na sąsiedniej liście.
Należy to zrobić, ponieważ chcesz zastosować warunek sumy kontrolnej do testu, a nie do testu wstępnego.
W okienku Warunki testu wybierz pozycję Suma kontrolna danych na liście, a następnie wybierz pozycję Dodaj warunek testu.
W oknie Właściwości we właściwości Konfiguracja wybierz przycisk przeglądania ('...').
W oknie dialogowym Configuration for checksumCondition1 skonfiguruj połączenie z bazą danych.
Zastąp Transact-SQL w oknie dialogowym (w obszarze przycisku Edytuj połączenie ) następującym kodem:
BEGIN TRANSACTION -- Add a customer for this test with the name 'CustomerB' ; DECLARE @NewCustomerID AS INT, @RC AS INT, @CustomerName AS NVARCHAR (40); SELECT @RC = 0, @NewCustomerID = 0, @CustomerName = N'Fictitious Customer'; IF NOT EXISTS (SELECT * FROM [Sales].[Customer] WHERE CustomerName = @CustomerName) BEGIN EXECUTE @NewCustomerID = [Sales].[uspNewCustomer] @CustomerName; END DECLARE @CustomerID AS INT, @Amount AS INT, @OrderDate AS DATETIME, @Status AS CHAR (1); SELECT @RC = 0, @CustomerID = 0, @CustomerName = N'Fictitious Customer', @OrderDate = getdate(), @Status = 'O'; -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script. SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName; -- delete any old records in the Orders table and clear out the YTD Sales/Orders fields DELETE [Sales].[Orders] WHERE [CustomerID] = @CustomerID; UPDATE [Sales].[Customer] SET YTDOrders = 0, YTDSales = 0 WHERE [CustomerID] = @CustomerID; EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 100, @OrderDate, @Status; EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 50, @OrderDate, @Status; EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 5, @OrderDate, @Status; COMMIT TRANSACTION; DECLARE @FilledDate AS DATETIME; DECLARE @OrderID AS INT; SELECT @RC = 0, @CustomerID = 0, @OrderID = 0, @CustomerName = N'Fictitious Customer', @Amount = 100, @FilledDate = getdate(), @Status = 'O'; SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName; EXECUTE @RC = [Sales].[uspShowOrderDetails] @CustomerID; SELECT @RC AS RC; -- place 3 orders for that customer -- ssNoVersion unit test for Sales.uspFillOrder -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script. -- fill an order for that customerTen kod łączy kod Transact-SQL z testu wstępnego z Transact-SQL z samego testu. Oba te elementy muszą zwracać te same wyniki, które test zwraca po uruchomieniu.
Wybierz Pobierz. (W razie potrzeby wybierz pozycję Pobierz , dopóki nie zobaczysz danych).
Określona Transact-SQL jest wykonywana, a suma kontrolna jest obliczana dla zwracanych danych.
Kliknij przycisk OK.
Obliczona suma kontrolna jest przechowywana z warunkiem testu. Oczekiwana suma kontrolna jest wyświetlana w kolumnie Wartość warunku testu sumy kontrolnej danych.
W menu Plik wybierz pozycję Zapisz wszystko.
Na tym etapie możesz przystąpić do uruchamiania testów.
Uruchamianie testów jednostkowych programu SQL Server
Uruchamianie testów jednostkowych programu SQL Server
W menu Test wskaż pozycję Windows, a następnie wybierz pozycję Widok testu w programie Visual Studio 2010 lub Eksploratorze testów w programie Visual Studio 2012.
W oknie Widok testu (Visual Studio 2010) wybierz pozycję Odśwież na pasku narzędzi, aby zaktualizować listę testów. Aby wyświetlić listę testów w Eksploratorze testów (Visual Studio 2012), skompiluj rozwiązanie.
Okno Widok testu lub Eksplorator testów zawiera listę testów utworzonych wcześniej w tym przewodniku i do których dodano instrukcje Transact-SQL i warunki testowe. Test o nazwie TestMethod1 jest pusty i nie jest używany w tym przewodniku.
Kliknij prawym przyciskiem myszy Sales_uspNewCustomerTest, a następnie wybierz Uruchom zaznaczenie.
Program Visual Studio używa określonego kontekstu uprzywilejowanego w celu nawiązania połączenia z bazą danych i zastosowania planu generowania danych. Program Visual Studio następnie przełącza się do kontekstu wykonywania przed uruchomieniem skryptu Transact-SQL w teście. Na koniec program Visual Studio ocenia wyniki skryptu Transact-SQL względem tych, które zostały określone w warunku testu, a wynik powodzenia lub niepowodzenia pojawi się w oknie Wyniki testów .
Wyświetl wynik w oknie Wyniki testu .
Test zakończy się pomyślnie, co oznacza, że
SELECTinstrukcja zwraca jeden wiersz po uruchomieniu.Powtórz krok 3 dla
Sales_uspPlaceNewOrderTesttestów ,Sales_uspFillOrderTestiSales_uspShowOrderDetailsTest. Wyniki powinny być następujące:Test Oczekiwany wynik Sales_uspPlaceNewOrderTestPrzepustka Sales_uspShowOrderDetailsTestPrzepustka Sales_uspFillOrderTestKończy się niepowodzeniem z powodu następującego błędu: ScalarValueCondition Condition (scalarValueCondition2) Failed: ResultSet 1 Row 1 Column 1: values do not match, actual '-100' expected '100'.Ten błąd występuje, ponieważ definicja procedury składowanej zawiera drobny błąd.Następnie popraw błąd i uruchom ponownie test.
Poprawianie błędu w Sales.uspFillOrder
W węźle Projekt Eksploratora obiektów programu SQL Server dla bazy danych kliknij dwukrotnie procedurę składowaną uspFillOrder, aby otworzyć jej definicję w edytorze Transact-SQL.
W definicji znajdź następującą instrukcję Transact-SQL:
UPDATE [Sales].[Customer] SET YTDSales = YTDSales - @Delta WHERE [CustomerID] = @CustomerID;Zmień klauzulę
SETw instrukcji, aby odpowiadała następującej instrukcji:UPDATE [Sales].[Customer] SET YTDSales = YTDSales + @Delta WHERE [CustomerID] = @CustomerID;W menu Plik wybierz pozycję Zapisz uspFillOrder.sql.
W widoku testu kliknij prawym przyciskiem myszy Sales_uspFillOrderTest, a następnie wybierz polecenie Uruchom zaznaczenie.
Test zakończy się pomyślnie.
Dodawanie ujemnego testu jednostkowego
Możesz utworzyć test ujemny, aby sprawdzić, czy test zakończy się niepowodzeniem, gdy zakończy się niepowodzeniem. Jeśli na przykład spróbujesz anulować zamówienie, które zostało już wypełnione, test powinien zakończyć się niepowodzeniem. W tej części instrukcji utworzysz test jednostkowy negatywny dla procedury składowanej Sales.uspCancelOrder.
Aby utworzyć i zweryfikować test ujemny, należy wykonać następujące zadania:
Aktualizowanie procedury składowanej w celu przetestowania warunków awarii
Definiowanie nowego testu jednostkowego
Zmodyfikuj kod testu jednostkowego, aby wskazać, że spodziewane jest niepowodzenie.
Uruchamianie testu jednostkowego
Zaktualizuj procedurę składowaną
W węźle Projektów Eksploratora obiektów programu SQL Server dla bazy danych
SimpleUnitTestDBrozwiń węzeł Programmability, rozwiń węzeł Stored Procedures i kliknij dwukrotnie pozycjęuspCancelOrder.W edytorze Transact-SQL zaktualizuj definicję procedury, aby odpowiadała następującemu kodzie:
CREATE PROCEDURE [Sales].[uspCancelOrder] @OrderID INT AS BEGIN DECLARE @Delta AS INT, @CustomerID AS INT, @PriorStatus AS CHAR (1); BEGIN TRANSACTION; BEGIN TRY IF (NOT EXISTS (SELECT [CustomerID] FROM [Sales].[Orders] WHERE [OrderID] = @OrderID)) BEGIN -- Specify WITH LOG option so that the error is -- written to the application log. RAISERROR ('That order does not exist.', -- Message text 16, -- severity 1 -- state ) WITH LOG; END SELECT @Delta = [Amount], @CustomerID = [CustomerID], @PriorStatus = [Status] FROM [Sales].[Orders] WHERE [OrderID] = @OrderID; IF @PriorStatus <> 'O' BEGIN -- Specify WITH LOG option so that the error is -- written to the application log. RAISERROR ('You can only cancel open orders.', -- Message text 16, -- Severity 1 -- State ) WITH LOG; END ELSE BEGIN -- If we make it to here, then we can cancel the order. Update the status to 'X' first... UPDATE [Sales].[Orders] SET [Status] = 'X' WHERE [OrderID] = @OrderID -- and then remove the amount from the YTDOrders for the customer ; UPDATE [Sales].[Customer] SET YTDOrders = YTDOrders - @Delta WHERE [CustomerID] = @CustomerID; COMMIT TRANSACTION; RETURN 1; -- indicate success END END TRY BEGIN CATCH DECLARE @ErrorMessage AS NVARCHAR (4000); DECLARE @ErrorSeverity AS INT; DECLARE @ErrorState AS INT; SELECT @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); ROLLBACK; RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState); RETURN 0; END CATCH END -- Use RAISERROR inside the CATCH block to return -- error information about the original error that -- caused execution to jump to the CATCH block. -- Message text -- Severity -- State -- indicate failureW menu Plik wybierz pozycję Zapisz uspCancelOrder.sql.
Naciśnij F5 , aby wdrożyć plik
SimpleUnitTestDB.Wdrażasz aktualizacje w procedurze składowanej
uspCancelOrder. Nie zmieniono żadnych innych obiektów, więc tylko ta procedura składowana jest aktualizowana.Następnie zdefiniuj skojarzony test jednostkowy dla tej procedury.
Napisz test jednostkowy SQL Server dla procedury uspCancelOrder
Na pasku nawigacyjnym projektanta testów jednostkowych programu SQL Server wybierz pozycję Sales_uspCancelOrderTest i upewnij się, że test został wyróżniony na sąsiedniej liście.
Po wykonaniu tego kroku możesz utworzyć skrypt testowy dla akcji testowej w teście jednostkowym.
Zaktualizuj instrukcje Transact-SQL w edytorze Transact-SQL, aby odpowiadały następującym instrukcjom:
-- ssNoVersion unit test for Sales.uspFillOrder DECLARE @RC AS INT, @CustomerID AS INT, @Amount AS INT, @FilledDate AS DATETIME, @Status AS CHAR (1); DECLARE @CustomerName AS NVARCHAR (40), @OrderID AS INT; SELECT @RC = 0, @CustomerID = 0, @OrderID = 0, @CustomerName = N'Fictitious Customer', @Amount = 100, @FilledDate = getdate(), @Status = 'O'; -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script. SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName; -- Get the most recently added order. SELECT @OrderID = MAX([OrderID]) FROM [Sales].[Orders] WHERE [CustomerID] = @CustomerID; -- try to cancel an order for that customer that has already been filled EXECUTE @RC = [Sales].[uspCancelOrder] @OrderID; SELECT @RC AS RC;W okienku Warunki testu wybierz niejednoznaczny warunek testu, a następnie wybierz ikonę Usuń warunek testu .
W okienku Warunki testu wybierz pozycję Wartość skalarna na liście, a następnie wybierz ikonę Dodaj warunek testu .
W oknie Właściwości ustaw właściwość Oczekiwana wartość na 0.
Na pasku nawigacyjnym projektanta testów jednostkowych programu SQL Server wybierz pozycję Sales_uspCancelOrderTest i upewnij się, że na sąsiedniej liście wyróżniono pozycję Pre-Test . Po wykonaniu tego kroku można określić instrukcje, które umieszczają dane w stanie wymaganym do wykonania testu. Aby można było złożyć zamówienie, w tym przykładzie należy najpierw utworzyć rekord
Customer.Wybierz Kliknij tutaj, aby utworzyć, aby utworzyć skrypt przedtestowy.
Zaktualizuj instrukcje Transact-SQL w edytorze Transact-SQL, aby odpowiadały następującym instrukcjom:
/* Add Transact-SQL statements here to run before the test script is run. */ BEGIN TRANSACTION -- Add a customer for this test with the name 'CustomerB' ; DECLARE @NewCustomerID AS INT, @RC AS INT, @CustomerName AS NVARCHAR (40); SELECT @RC = 0, @NewCustomerID = 0, @CustomerName = N'Fictitious Customer'; IF NOT EXISTS (SELECT * FROM [Sales].[Customer] WHERE CustomerName = @CustomerName) BEGIN EXECUTE @NewCustomerID = [Sales].[uspNewCustomer] @CustomerName; END DECLARE @CustomerID AS INT, @Amount AS INT, @OrderDate AS DATETIME, @FilledDate AS DATETIME, @Status AS CHAR (1), @OrderID AS INT; SELECT @RC = 0, @CustomerID = 0, @OrderID = 0, @CustomerName = N'Fictitious Customer', @Amount = 100, @OrderDate = getdate(), @FilledDate = getdate(), @Status = 'O'; -- NOTE: Assumes that you inserted a Customer record with CustomerName='Fictitious Customer' in the pre-test script. SELECT @CustomerID = [CustomerID] FROM [Sales].[Customer] WHERE [CustomerName] = @CustomerName; -- delete any old records in the Orders table and clear out the YTD Sales/Orders fields DELETE [Sales].[Orders] WHERE [CustomerID] = @CustomerID; UPDATE [Sales].[Customer] SET YTDOrders = 0, YTDSales = 0 WHERE [CustomerID] = @CustomerID; EXECUTE @OrderID = [Sales].[uspPlaceNewOrder] @CustomerID, @Amount, @OrderDate, @Status; EXECUTE @RC = [Sales].[uspFillOrder] @OrderID, @FilledDate; COMMIT TRANSACTION; -- place an order for that customer -- fill the order for that customerW menu Plik wybierz pozycję Zapisz wszystko.
Na tym etapie możesz przystąpić do uruchamiania testów.
Uruchamianie testów jednostkowych programu SQL Server
W widoku testowym kliknij prawym przyciskiem myszy Sales_uspCancelOrderTest, a następnie wybierz polecenie Uruchom zaznaczenie.
Wyświetl wynik w oknie Wyniki testu .
Test kończy się niepowodzeniem i pojawia się następujący błąd:
Test method TestProject1.SqlServerUnitTests1.Sales_uspCancelOrderTest threw exception: System.Data.SqlClient.SqlException: You can only cancel open orders.Następnie zmodyfikujesz kod, aby wskazać, że wyjątek jest oczekiwany.
Modyfikowanie kodu dla testu jednostkowego
W Eksploratorze rozwiązań rozwiń TestProject1, kliknij prawym przyciskiem myszy SqlServerUnitTests1.cs i wybierz Wyświetl kod.
W edytorze kodu przejdź do metody Sales_uspCancelOrderTest. Zmodyfikuj atrybuty metody, aby odpowiadały następującemu kodzie:
[TestMethod(), ExpectedSqlException(Severity=16, MatchFirstError=false, State=1)] public void Sales_uspCancelOrderTest()Należy określić, że spodziewasz się zobaczyć określony wyjątek. Opcjonalnie możesz określić określony numer błędu. Jeśli ten atrybut nie zostanie dodany, test jednostkowy zakończy się niepowodzeniem, a w oknie Wyniki testu pojawi się komunikat
W menu Plik wybierz pozycję Zapisz SqlServerUnitTests1.cs.
Następnie ponownie przeprowadź test jednostkowy, aby sprawdzić, czy kończy się niepowodzeniem zgodnie z oczekiwaniami.
Ponowne uruchamianie testów jednostkowych programu SQL Server
W widoku testowym kliknij prawym przyciskiem myszy Sales_uspCancelOrderTest, a następnie wybierz polecenie Uruchom zaznaczenie.
Wyświetl wynik w oknie Wyniki testu .
Test przebiegnie pomyślnie, co oznacza, że procedura nie powiodła się, gdy miała zakończyć się niepowodzeniem.