Database
 sql >> Baza danych >  >> RDS >> Database

Sztuka wyodrębniania zależności i danych w testach jednostkowych bazy danych

Wszyscy programiści baz danych w mniejszym lub większym stopniu piszą testy jednostkowe bazy danych, które nie tylko pomagają we wczesnym wykrywaniu błędów, ale także oszczędzają dużo czasu i wysiłku, gdy nieoczekiwane zachowanie obiektów bazy danych staje się problemem produkcyjnym.

Obecnie istnieje wiele platform do testowania jednostek baz danych, takich jak tSQLt, wraz z narzędziami do testowania jednostek innych firm, w tym dbForge Unit Test.

Z jednej strony zaletą korzystania z narzędzi testowych innych firm jest to, że zespół programistów może natychmiast tworzyć i uruchamiać testy jednostkowe z dodatkowymi funkcjami. Ponadto użycie frameworka testowego bezpośrednio zapewnia większą kontrolę nad testami jednostkowymi. Dlatego możesz dodać więcej funkcji do samej struktury testów jednostkowych. Jednak w tym przypadku Twój zespół musi mieć czas i pewien poziom wiedzy, aby to zrobić.

W tym artykule omówiono niektóre standardowe praktyki, które mogą pomóc nam ulepszyć sposób pisania testów jednostkowych baz danych.

Najpierw przejrzyjmy kilka kluczowych koncepcji testowania jednostkowego bazy danych.

Co to jest testowanie jednostek bazy danych

Według Dave'a Greena testy jednostkowe bazy danych zapewniają, że małe jednostki bazy danych, takie jak tabele, widoki, procedury składowane itp., działają zgodnie z oczekiwaniami.

Testy jednostkowe bazy danych są pisane w celu sprawdzenia, czy kod spełnia wymagania biznesowe.

Na przykład, jeśli otrzymasz takie wymaganie, jak „Bibliotekarz (użytkownik końcowy) powinien mieć możliwość dodawania nowych książek do biblioteki (System Informacji Zarządzania)”, musisz pomyśleć o zastosowaniu testów jednostkowych dla procedury składowanej, aby sprawdzić, czy może dodać nową książkę do książki tabela.

Czasami seria testów jednostkowych zapewnia, że ​​kod spełnia wymagania. Dlatego większość frameworków do testowania jednostkowego, w tym tSQLt, pozwala na grupowanie powiązanych testów jednostkowych w pojedynczą klasę testową zamiast uruchamiania pojedynczych testów.

Zasada AAA

Warto wspomnieć o 3-stopniowej zasadzie testowania jednostkowego, która jest standardową praktyką pisania testów jednostkowych. Zasada AAA jest podstawą testów jednostkowych i składa się z następujących kroków:

  1. Ułóż/złóż
  2. Działaj
  3. Potwierdź

Ułóż Sekcja jest pierwszym krokiem w pisaniu testów jednostkowych bazy danych. Prowadzi przez konfigurację obiektu bazy danych do testowania i ustawienie oczekiwanych wyników.

Ustawa sekcja ma miejsce, gdy obiekt bazy danych (testowany) jest wywoływany w celu wygenerowania rzeczywistego wyniku.

Zatwierdzenie step zajmuje się dopasowaniem rzeczywistego wyniku do oczekiwanego i sprawdza, czy test wypadł pomyślnie, czy nie.

Przyjrzyjmy się tym metodom na konkretnych przykładach.

Jeśli utworzymy test jednostkowy, aby sprawdzić, czy AddProduct procedura składowana może dodać nowy produkt, ustawiamy Produkt i Oczekiwany produkt tabele po dodaniu produktu. W tym przypadku metoda znajduje się w sekcji Rozmieszczanie/Montaż.

Wywołanie procedury AddProduct i umieszczenie wyniku w tabeli Product opisano w sekcji Act.

Część Assert po prostu dopasowuje tabelę Product do tabeli ExpectedProduct, aby sprawdzić, czy procedura składowana została wykonana pomyślnie, czy nie.

Zrozumienie zależności w testowaniu jednostkowym

Do tej pory omówiliśmy podstawy testowania jednostkowego bazy danych i znaczenie zasady AAA (Assemble, Act, and Assert) podczas tworzenia standardowego testu jednostkowego.

Teraz skupmy się na innym ważnym elemencie układanki – zależnościach w testach jednostkowych.

Oprócz przestrzegania zasady AAA i skupiania się tylko na konkretnym obiekcie bazy danych (testowanym), musimy również znać zależności, które mogą wpływać na testy jednostkowe.

Najlepszym sposobem zrozumienia zależności jest przyjrzenie się przykładowi testu jednostkowego.

Konfiguracja przykładowej bazy danych pracowników

Aby przejść dalej, utwórz przykładową bazę danych i nazwij ją EmployeesSample :

-- Create the Employees sample database to demonstrate unit testing

CREATE DATABASE EmployeesSample;
GO

Teraz utwórz Pracownika tabela w przykładowej bazie danych:

-- Create the Employee table in the sample database

USE EmployeesSample

CREATE TABLE Employee
  (EmployeeId INT PRIMARY KEY IDENTITY(1,1),
  NAME VARCHAR(40),
  StartDate DATETIME2,
  Title VARCHAR(50)
  );
GO

Wypełnianie przykładowych danych

Wypełnij tabelę, dodając kilka rekordów:

-- Adding data to the Employee table
INSERT INTO Employee (NAME, StartDate, Title)
  VALUES 
  ('Sam','2018-01-01', 'Developer'),
  ('Asif','2017-12-12','Tester'),
  ('Andy','2016-10-01','Senior Developer'),
  ('Peter','2017-11-01','Infrastructure Engineer'),
  ('Sadaf','2015-01-01','Business Analyst');
GO

Tabela wygląda tak:

-- View the Employee table

  SELECT e.EmployeeId
        ,e.NAME
        ,e.StartDate
        ,e.Title FROM  Employee e;
GO

Proszę zauważyć, że w tym artykule używam dbForge Studio dla SQL Server. W związku z tym wygląd danych wyjściowych może się różnić, jeśli ten sam kod zostanie uruchomiony w programie SSMS (SQL Server Management Studio). Nie ma różnicy, jeśli chodzi o skrypty i ich wyniki.

Wymaganie dodania nowego pracownika

Teraz, jeśli zostało odebrane żądanie dodania nowego pracownika, najlepszym sposobem na jego spełnienie jest utworzenie procedury składowanej, która może pomyślnie dodać nowego pracownika do tabeli.

Aby to zrobić, utwórz procedurę składowaną AddEmployee w następujący sposób:

-- Stored procedure to add a new employee 

CREATE PROCEDURE AddEmployee @Name VARCHAR(40),
@StartDate DATETIME2,
@Title VARCHAR(50)
AS
BEGIN
  SET NOCOUNT ON
    INSERT INTO Employee (NAME, StartDate, Title)
  VALUES (@Name, @StartDate, @Title);
END

Test jednostkowy w celu sprawdzenia, czy wymagania są spełnione

Zamierzamy napisać test jednostkowy bazy danych, aby sprawdzić, czy procedura składowana AddEmployee spełnia wymagania dodania nowego rekordu do tabeli Employee.

Skoncentrujmy się na zrozumieniu filozofii testów jednostkowych, symulując kod testu jednostkowego, zamiast pisać test jednostkowy za pomocą platformy testowej lub narzędzia do testowania jednostkowego innej firmy.

Symulowanie testów jednostkowych i stosowanie zasady AAA w SQL

Pierwszą rzeczą, którą musimy zrobić, to naśladować zasadę AAA w SQL, ponieważ nie będziemy używać żadnych frameworków do testów jednostkowych.

Sekcja Montaż jest stosowana, gdy rzeczywiste i oczekiwane tabele są zwykle konfigurowane wraz z zapełnianiem oczekiwanej tabeli. W tym kroku możemy użyć zmiennych SQL, aby zainicjować oczekiwaną tabelę.

Sekcja Act jest używana, gdy aktualna procedura składowana jest wywoływana w celu wstawienia danych do rzeczywistej tabeli.

Sekcja Assert ma miejsce, gdy oczekiwana tabela pasuje do rzeczywistej tabeli. Symulacja części Assert jest nieco trudna i można ją osiągnąć, wykonując następujące czynności:

  • Liczenie wspólnych (pasujących) wierszy między dwiema tabelami, które powinny wynosić 1 (ponieważ oczekiwana tabela ma tylko jeden rekord, który powinien pasować do rzeczywistej tabeli)
  • Wykluczenie rzeczywistych rekordów tabeli z oczekiwanych rekordów tabeli powinno być równe 0 (jeśli rekord w oczekiwanej tabeli istnieje również w rzeczywistej tabeli, wówczas wykluczenie wszystkich rzeczywistych rekordów tabeli z oczekiwanej tabeli powinno zwrócić 0)

Skrypt SQL wygląda następująco:

[rozwiń tytuł=”Kod”]

-- Simulating unit test to test the AddEmployee stored procedure

CREATE PROCEDURE TestAddEmployee
AS
BEGIN
  -- (1) Assemble

  -- Set up new employee data
  DECLARE @EmployeeId INT = 6
         ,@NAME VARCHAR(40) = 'Adil'
         ,@StartDate DATETIME2 = '2018-03-01'
         ,@Title VARCHAR(50) = 'Development Manager'


  -- Set up the expected table
  CREATE TABLE #EmployeeExpected (
    EmployeeId INT PRIMARY KEY IDENTITY (6, 1) 
    -- the expected table EmployeeId should begin with 6 
    -- since the actual table has already got 5 records and 
    -- the next EmployeeId in the actual table is 6
   ,NAME VARCHAR(40)
   ,StartDate DATETIME2
   ,Title VARCHAR(50)
  );

  -- Add the expected table data
  INSERT INTO #EmployeeExpected (NAME, StartDate, Title)
    VALUES (@NAME, @StartDate, @Title);

  -- (2) Act

  -- Call AddEmployee to add new employee data to the Employee table
  INSERT INTO Employee
  EXEC AddEmployee @NAME
                  ,@StartDate
                  ,@Title



  -- (3) Assert

  -- Match the actual table with the expected table
  DECLARE @ActualAndExpectedTableCommonRecords INT = 0 -- we assume that expected and actual table records have nothing in common

  SET @ActualAndExpectedTableCommonRecords = (SELECT
      COUNT(*)
    FROM (SELECT
        e.EmployeeId
       ,e.NAME
       ,e.StartDate
       ,e.Title
      FROM Employee e
      INTERSECT
      SELECT
        ee.EmployeeId
       ,ee.NAME
       ,ee.StartDate
       ,ee.Title
      FROM #EmployeeExpected ee) AS A)


  DECLARE @ExpectedTableExcluldingActualTable INT = 1 -- we assume that expected table has records which do not exist in the actual table

  SET @ExpectedTableExcluldingActualTable = (SELECT
      COUNT(*)
    FROM (SELECT
        ee.EmployeeId
       ,ee.NAME
       ,ee.StartDate
       ,ee.Title
      FROM #EmployeeExpected ee
      EXCEPT
      SELECT
        e.EmployeeId
       ,e.NAME
       ,e.StartDate
       ,e.Title
      FROM Employee e) AS A)


  IF @ActualAndExpectedTableCommonRecords = 1
    AND @ExpectedTableExcluldingActualTable = 0
    PRINT '*** Test Passed! ***'
  ELSE
    PRINT '*** Test Failed! ***'

END

[/rozwiń]

Przeprowadzanie symulowanego testu jednostkowego

Po utworzeniu procedury składowanej wykonaj ją za pomocą symulowanego testu jednostkowego:

-- Running simulated unit test to check the AddEmployee stored procedure
EXEC TestAddEmployee

Dane wyjściowe są następujące:

Gratulacje! Test jednostki bazy danych przeszedł pomyślnie.

Identyfikacja problemów w formie zależności w teście jednostkowym

Czy możemy wykryć coś złego w utworzonym przez nas teście jednostkowym, mimo że został napisany i został pomyślnie uruchomiony?

Jeśli dokładnie przyjrzymy się konfiguracji testu jednostkowego (część Assemble), oczekiwana tabela ma niepotrzebne powiązanie z kolumną tożsamości:

Przed napisaniem testu jednostkowego dodaliśmy już 5 rekordów do tabeli rzeczywistej (Pracownik). Tak więc w konfiguracji testu kolumna tożsamości dla oczekiwanej tabeli zaczyna się od 6. Oznacza to jednak, że zawsze oczekujemy, że 5 rekordów w tabeli rzeczywistej (Pracownik) będzie pasować do tabeli oczekiwanej (#EmployeeExpected).

Aby zrozumieć, jak może to wpłynąć na test jednostkowy, spójrzmy teraz na rzeczywistą tabelę (Pracownik):

Dodaj kolejny rekord do tabeli Pracownik:

-- Adding a new record to the Employee table

INSERT INTO Employee (NAME, StartDate, Title)
  VALUES ('Mark', '2018-02-01', 'Developer');

Spójrz teraz na tabelę Pracownik:

Usuń EmpoyeeId 6 (Adil), aby test jednostkowy mógł działać na własnej wersji EmployeeId 6 (Adil), a nie na wcześniej zapisanym rekordzie.

-- Deleting the previously created EmployeeId: 6 (Adil) record from the Employee table

DELETE FROM Employee
  WHERE EmployeeId=6

Uruchom symulowany test jednostkowy i zobacz wyniki:

-- Running simulated unit test to check the AddEmployee stored procedure
EXEC TestAddEmployee

Tym razem test się nie powiódł. Odpowiedź znajduje się w zestawie wyników tabeli Pracownik, jak pokazano poniżej:

Powiązanie identyfikatora pracownika w teście jednostkowym, jak wspomniano powyżej, nie działa, gdy ponownie uruchamiamy test jednostkowy po dodaniu nowego rekordu i usunięciu poprzednio dodanego rekordu pracownika.

W teście występują trzy typy zależności:

  1. Zależność danych
  2. Zależność kluczowych ograniczeń
  3. Zależność kolumny tożsamości

Zależność danych

Przede wszystkim ten test jednostkowy zależy od danych w bazie danych. Według Dave'a Greena, jeśli chodzi o bazę danych testów jednostkowych, same dane są zależnością.

Oznacza to, że test jednostkowy bazy danych nie powinien opierać się na danych w bazie danych. Na przykład test jednostkowy powinien zawierać rzeczywiste dane do wstawienia do obiektu bazy danych (tabeli), a nie polegać na danych już istniejących w bazie danych, które można usunąć lub zmodyfikować.

W naszym przypadku fakt, że pięć rekordów zostało już wstawionych do rzeczywistej tabeli Employee, jest zależnością danych, której należy zapobiegać, ponieważ nie powinniśmy naruszać filozofii testów jednostkowych, która mówi, że testowana jest tylko jednostka kodu.

Innymi słowy, dane testowe nie powinny opierać się na rzeczywistych danych w bazie danych.

Zależność kluczowych ograniczeń

Inną zależnością jest zależność ograniczenia klucza, co oznacza, że ​​kolumna klucza podstawowego EmployeeId jest również zależnością. Należy temu zapobiec, aby napisać dobry test jednostkowy. Jednak do przetestowania ograniczenia klucza podstawowego wymagany jest oddzielny test jednostkowy.

Na przykład, aby przetestować procedurę składowaną AddEmployee, należy usunąć klucz podstawowy tabeli Pracownik, aby można było przetestować obiekt bez obaw o naruszenie klucza podstawowego.

Zależność kolumny tożsamości

Podobnie jak ograniczenie klucza podstawowego, kolumna tożsamości jest również zależnością. W związku z tym nie ma potrzeby testowania logiki automatycznego przyrostu kolumny tożsamości dla procedury AddEmployee; należy tego unikać za wszelką cenę.

Izolowanie zależności w testach jednostkowych

Możemy zapobiec wszystkim trzem zależnościom, tymczasowo usuwając ograniczenia z tabeli, a następnie uniezależniając się od danych w bazie danych dla testu jednostkowego. W ten sposób pisze się standardowe testy jednostkowe bazy danych.

W takim przypadku można by zapytać, skąd pochodzą dane do tabeli Pracownik. Odpowiedź brzmi:tabela zostaje wypełniona danymi testowymi zdefiniowanymi w teście jednostkowym.

Zmienianie zapisanej procedury testu jednostkowego

Usuńmy teraz zależności w naszym teście jednostkowym:

[rozwiń tytuł=”Kod”]

-- Simulating dependency free unit test to test the AddEmployee stored procedure
ALTER PROCEDURE TestAddEmployee
AS
BEGIN
  -- (1) Assemble

  -- Set up new employee data
  DECLARE @NAME VARCHAR(40) = 'Adil'
         ,@StartDate DATETIME2 = '2018-03-01'
         ,@Title VARCHAR(50) = 'Development Manager'

  -- Set actual table
  DROP TABLE Employee -- drop table to remove dependencies

  CREATE TABLE Employee -- create a table without dependencies (PRIMARY KEY and IDENTITY(1,1))
  (
    EmployeeId INT DEFAULT(0)
   ,NAME VARCHAR(40)
   ,StartDate DATETIME2
   ,Title VARCHAR(50)
  )

  -- Set up the expected table without dependencies (PRIMARY KEY and IDENTITY(1,1)
  CREATE TABLE #EmployeeExpected (
    EmployeeId INT DEFAULT(0)
   ,NAME VARCHAR(40)
   ,StartDate DATETIME2
   ,Title VARCHAR(50)
  )

  -- Add the expected table data
  INSERT INTO #EmployeeExpected (NAME, StartDate, Title)
    VALUES (@NAME, @StartDate, @Title)

  -- (2) Act

  -- Call AddEmployee to add new employee data to the Employee table
  EXEC AddEmployee @NAME
                  ,@StartDate
                  ,@Title
 
  -- (3) Assert

  -- Match the actual table with the expected table
  DECLARE @ActualAndExpectedTableCommonRecords INT = 0 -- we assume that the expected and actual table records have nothing in common

  SET @ActualAndExpectedTableCommonRecords = (SELECT
      COUNT(*)
    FROM (SELECT
        e.EmployeeId
       ,e.NAME
       ,e.StartDate
       ,e.Title
      FROM Employee e
      INTERSECT
      SELECT
        ee.EmployeeId
       ,ee.NAME
       ,ee.StartDate
       ,ee.Title
      FROM #EmployeeExpected ee) AS A)


  DECLARE @ExpectedTableExcluldingActualTable INT = 1 -- we assume that the expected table has records which donot exist in actual table

  SET @ExpectedTableExcluldingActualTable = (SELECT
      COUNT(*)
    FROM (SELECT
        ee.EmployeeId
       ,ee.NAME
       ,ee.StartDate
       ,ee.Title
      FROM #EmployeeExpected ee
      EXCEPT
      SELECT
        e.EmployeeId
       ,e.NAME
       ,e.StartDate
       ,e.Title
      FROM Employee e) AS A)


  IF @ActualAndExpectedTableCommonRecords = 1
    AND @ExpectedTableExcluldingActualTable = 0
    PRINT '*** Test Passed! ***'
  ELSE
    PRINT '*** Test Failed! ***'

  -- View the actual and expected tables before comparison
    SELECT e.EmployeeId
          ,e.NAME
          ,e.StartDate
          ,e.Title FROM Employee e

      SELECT    ee.EmployeeId
               ,ee.NAME
               ,ee.StartDate
               ,ee.Title FROM #EmployeeExpected ee
  
  -- Reset the table (Put back constraints after the unit test)
  DROP TABLE Employee
  DROP TABLE #EmployeeExpected

  CREATE TABLE Employee (
    EmployeeId INT PRIMARY KEY IDENTITY (1, 1)
   ,NAME VARCHAR(40)
   ,StartDate DATETIME2
   ,Title VARCHAR(50)
  );

END

[/rozwiń]

Przeprowadzanie symulowanego testu jednostkowego wolnego od zależności

Uruchom symulowany test jednostkowy, aby zobaczyć wyniki:

-- Running the dependency-free simulated unit test to check the AddEmployee stored procedure

EXEC TestAddEmployee

Uruchom ponownie test jednostkowy, aby sprawdzić procedurę składowaną AddEmployee:

-- Running the dependency-free simulated unit test to check the AddEmployee stored procedure

EXEC TestAddEmployee

Gratulacje! Zależności z testu jednostkowego zostały pomyślnie usunięte.

Teraz, nawet jeśli dodamy nowy rekord lub zestaw nowych rekordów do tabeli Employee, nie wpłynie to na nasz test jednostkowy, ponieważ pomyślnie usunęliśmy dane i zależności ograniczeń z testu.

Tworzenie testu jednostkowego bazy danych przy użyciu tSQLt

Następnym krokiem jest utworzenie prawdziwego testu jednostkowego bazy danych na podstawie symulowanego testu jednostkowego.

Jeśli używasz SSMS (SQL Server Management Studio), będziesz musiał zainstalować framework tSQLt, utworzyć klasę testową i włączyć CLR przed napisaniem i uruchomieniem testu jednostkowego.

Jeśli używasz dbForge Studio dla SQL Server, możesz utworzyć test jednostkowy, klikając prawym przyciskiem myszy procedurę składowaną AddEmployee, a następnie klikając „Test jednostkowy” => „Dodaj nowy test…”, jak pokazano poniżej:

Aby dodać nowy test, wypełnij wymagane informacje o teście jednostkowym:

Aby napisać test jednostkowy, użyj następującego skryptu:

--  Comments here are associated with the test.
--  For test case examples, see: http://tsqlt.org/user-guide/tsqlt-tutorial/
CREATE PROCEDURE [BasicTests].[test if new employee can be added]
AS
BEGIN
  --Assemble
  DECLARE @NAME VARCHAR(40) = 'Adil'
         ,@StartDate DATETIME2 = '2018-03-01'
         ,@Title VARCHAR(50) = 'Development Manager'


  EXEC tSQLt.FakeTable "dbo.Employee" -- This will create a dependency-free copy of the Employee table
  
  CREATE TABLE BasicTests.Expected -- Create the expected table
  (
    EmployeeId INT 
    ,NAME VARCHAR(40)
   ,StartDate DATETIME2
   ,Title VARCHAR(50)
  )


  -- Add the expected table data
  INSERT INTO BasicTests.Expected (NAME, StartDate, Title)
    VALUES (@NAME, @StartDate, @Title)

  --Act
  EXEC AddEmployee @Name -- Insert data into the Employee table
                  ,@StartDate 
                  ,@Title 
  

  --Assert 
  EXEC tSQLt.AssertEqualsTable @Expected = N'BasicTests.Expected'
                              ,@Actual = N'dbo.Employee'
                              ,@Message = N'Actual table matched with expected table'
                              ,@FailMsg = N'Actual table does not match with expected table'

END;
GO

Następnie uruchom test jednostkowy bazy danych:

Gratulacje! Pomyślnie stworzyliśmy i uruchomiliśmy test jednostkowy bazy danych, który jest wolny od zależności.

Rzeczy do zrobienia

Otóż ​​to. Po zapoznaniu się z tym artykułem możesz już wyizolować zależności z testów jednostkowych bazy danych i utworzyć test jednostkowy bazy danych wolny od zależności danych i ograniczeń. W rezultacie możesz poprawić swoje umiejętności, wykonując następujące czynności:

  1. Spróbuj dodać procedurę składowaną Usuń pracownika i utwórz symulowany test jednostkowy bazy danych dla Usuń pracownika z zależnościami, aby sprawdzić, czy nie powiedzie się w określonych warunkach
  2. Spróbuj dodać procedurę składowaną Usuń pracownika i utwórz test jednostkowy bazy danych wolny od zależności, aby sprawdzić, czy można usunąć pracownika
  3. Spróbuj dodać procedurę składowaną Wyszukaj pracownika i utwórz symulowany test jednostkowy bazy danych z zależnościami, aby sprawdzić, czy można wyszukać pracownika
  4. Spróbuj dodać procedurę składowaną Wyszukaj pracownika i utwórz test jednostkowy bazy danych wolny od zależności, aby sprawdzić, czy można wyszukać pracownika
  5. Wypróbuj bardziej złożone wymagania, tworząc procedury składowane w celu spełnienia wymagań, a następnie pisząc testy jednostkowe bazy danych wolne od zależności, aby sprawdzić, czy testy przeszły pomyślnie, czy nie. Upewnij się jednak, że test jest powtarzalny i koncentruje się na testowaniu jednostki kodu

Przydatne narzędzie:

dbForge Unit Test – intuicyjny i wygodny GUI do wdrażania zautomatyzowanych testów jednostkowych w SQL Server Management Studio.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Wybierz Wyraźne

  2. Poprawność i ograniczenia

  3. Pakiet hostingowy na Chocolatey

  4. Anonimizacja identyfikatorów pośrednich w celu zmniejszenia ryzyka ponownej identyfikacji

  5. Mity dotyczące wydajności:Obcięcie nie może zostać wycofane