Scala for Backend Engineering & Functional Programming · Lekcja

Testowanie oparte na właściwościach

ScalaCheck

Lekcja 3 z 413 kroki

Testowanie oparte na właściwościach to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Scala for Backend Engineering & Functional Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.

Czym jest testowanie oparte na właściwościach?

W testowaniu opartym na właściwościach określasz ogólną właściwość, która powinna zachodzić dla wszystkich danych wejściowych, a framework generuje wiele losowych danych, próbując znaleźć kontrprzykład. Dzięki temu wykrywa przypadki brzegowe pomijane przez ręcznie napisane przykłady.

Przykład a właściwość

Test przykładowy sprawdza jeden przypadek: reverse(List(1,2,3)) == List(3,2,1). Właściwość określa regułę: dwukrotne odwrócenie zwraca oryginalną listę dla dowolnej listy. Framework sprawdza tę regułę dla setek wygenerowanych list.

ScalaCheck

ScalaCheck to biblioteka do testowania właściwości w Scali. Dodaj ją jako zależność testową; integruje się ze ScalaTest.

libraryDependencies += "org.scalatestplus" %% "scalacheck-1-17" % "3.2.18.0" % Test

forAll

Podstawową konstrukcją jest forAll: generuje losowe wartości i sprawdza ciało właściwości dla każdej z nich. W tym przykładzie testujemy przemienność dodawania.

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks

class AddSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyChecks {
  "addition" should "be commutative" in {
    forAll { (a: Int, b: Int) =>
      a + b shouldBe b + a
    }
  }
}

Właściwość round trip

Potężnym wzorcem jest round trip: kodowanie, a następnie dekodowanie (lub dwukrotne odwrócenie) powinno zwrócić oryginalną wartość dla dowolnych danych wejściowych.

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks

class RevSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyChecks {
  "reverse" should "be its own inverse" in {
    forAll { (xs: List[Int]) =>
      xs.reverse.reverse shouldBe xs
    }
  }
}

Generatory

ScalaCheck automatycznie udostępnia generatory Gen dla wbudowanych typów. Możesz także tworzyć własne, np. Gen.choose(1, 100) dla ograniczonej liczby całkowitej.

import org.scalacheck.Gen

val smallInt: Gen[Int] = Gen.choose(1, 100)
val nonEmpty: Gen[List[Int]] = Gen.nonEmptyListOf(Gen.choose(0, 9))

Używanie niestandardowego generatora

Przekaż generator do forAll, aby ograniczyć dane wejściowe, na przykład do liczb dodatnich.

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import org.scalacheck.Gen

class PosSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyChecks {
  "abs" should "stay positive" in {
    forAll(Gen.choose(1, 1000)) { (n: Int) =>
      math.abs(n) should be > 0
    }
  }
}

Zmniejszanie

Gdy właściwość nie przejdzie testu, ScalaCheck zmniejsza niepoprawne dane wejściowe do najmniejszego przykładu, dla którego test nadal kończy się niepowodzeniem. Zamiast ogromnej losowej listy otrzymujesz minimalny kontrprzykład, który łatwo debugować.

Właściwości warunkowe

Użyj whenever, aby ograniczyć właściwość do danych wejściowych spełniających warunek wstępny. Dane niespełniające tego warunku są odrzucane.

import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks

class DivSpec extends AnyFlatSpec with Matchers with ScalaCheckPropertyChecks {
  "division" should "hold for nonzero divisors" in {
    forAll { (a: Int, b: Int) =>
      whenever(b != 0) {
        (a / b) * b + (a % b) shouldBe a
      }
    }
  }
}

Dobre właściwości do testowania

Przydatne kategorie właściwości:

  • Round trip: kodowanie/dekodowanie, odwracanie/odwracanie.
  • Niezmienniki: sortowanie zachowuje długość.
  • Prawa algebraiczne: przemienność, łączność, element neutralny.

Kiedy tego używać

Testowanie właściwości uzupełnia testy przykładowe, ale ich nie zastępuje. Używaj go dla funkcji czystych z jasno określonymi regułami matematycznymi lub strukturalnymi. Zachowaj ukierunkowane testy przykładowe dla konkretnych znanych przypadków i regresji.

Szybki sprawdzian

Sprawdź swoją wiedzę o testowaniu opartym na właściwościach.

Podsumowanie

Nauczyłeś się testowania opartego na właściwościach za pomocą ScalaCheck:

  • Określaj właściwości prawdziwe dla wszystkich danych wejściowych; framework wygeneruje ich wiele.
  • forAll steruje generowaniem, a Gen tworzy niestandardowe dane wejściowe.
  • whenever dodaje warunki wstępne; niepoprawne dane są zmniejszane do minimalnych przykładów.
  • To świetne rozwiązanie dla round tripów, niezmienników i praw algebraicznych.
Bezpłatny start

Ucz się Scala dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
39
Lekcje
143

Często zadawane pytania

Czy lekcja „Testowanie oparte na właściwościach” jest bezpłatna?

Tak — pełny tekst „Testowanie oparte na właściwościach” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Scala for Backend Engineering & Functional Programming, przejdź na CoddyKit PRO. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.

Co nauczysz się w „Testowanie oparte na właściwościach”?

ScalaCheck Ćwiczysz Scala for Backend Engineering & Functional Programming z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Scala for Backend Engineering & Functional Programming?

Nie wymagamy żadnego doświadczenia. Scala for Backend Engineering & Functional Programming w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Testowanie oparte na właściwościach”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Scala for Backend Engineering & Functional Programming?

Tak. Każda lekcja Scala for Backend Engineering & Functional Programming zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Style ScalaTest
  2. Matchery
  3. Testowanie oparte na właściwościach
  4. Mockowanie i fixture’y
← Powrót do Scala for Backend Engineering & Functional Programming