Sdílet prostřednictvím


Testování jednotek pro poznámkové bloky

Testování jednotek vám pomůže zlepšit kvalitu a konzistenci kódu poznámkových bloků. Testování částí je přístup k testování samostatných jednotek kódu, jako jsou funkce, brzy a často. To vám pomůže rychleji najít problémy s kódem, odhalit chybné předpoklady o kódu dříve a zjednodušit celkové úsilí o kódování.

Tento článek je úvodem k základnímu testování částí pomocí funkcí. Pokročilé koncepty, jako jsou třídy testování jednotek a rozhraní, stejně jako použití zástupných procedur, napodobení a testovacích nástrojů, a také podporované při testování jednotek pro poznámkové bloky, jsou mimo rozsah tohoto článku. Tento článek se také nezabývá dalšími druhy testovacích metod, jako je testování integrace, testování systému, akceptační testování nebo nefunkční metody testování , jako je testování výkonnosti nebo testování použitelnosti.

Tento článek ukazuje následující:

  • Uspořádání funkcí a jejich testů jednotek
  • Jak psát funkce v Pythonu, R, Scala i uživatelem definovaných funkcích v SQL, které jsou dobře navržené pro testování jednotek.
  • Jak tyto funkce volat z poznámkových bloků Pythonu, R, Scala a SQL
  • Jak psát testy jednotek v Pythonu, R a Scala pomocí oblíbených testovacích architektur pytest pro Python, testthat pro R a ScalaTest pro Scala. Také jak napsat SQL, který testuje uživatelem definované funkce SQL (UDF SQL).
  • Jak tyto testy jednotek spouštět z poznámkových bloků Pythonu, R, Scala a SQL

Uspořádání funkcí a testů jednotek

Existuje několik běžných přístupů k uspořádání funkcí a jejich testů jednotek pomocí poznámkových bloků. Každý přístup má své výhody a výzvy.

Mezi běžné přístupy pro poznámkové bloky Python, R a Scala patří:

V případě poznámkových bloků Pythonu a R doporučuje Databricks ukládat funkce a testy jednotek mimo poznámkové bloky. Pro poznámkové bloky Scala doporučuje Databricks zahrnout funkce v jednom poznámkovém bloku a jejich testy jednotek v samostatném poznámkovém bloku.

Pro poznámkové bloky SQL doporučuje Databricks ukládat funkce jako uživatelem definované funkce SQL (UDF) ve schématech (označované také jako databáze). Tyto funkce definované uživatelem SQL a jejich testy jednotek pak můžete volat z poznámkových bloků SQL.

Psaní funkcí

Tato část popisuje jednoduchou sadu ukázkových funkcí, které určují následující:

  • Určuje, jestli tabulka existuje v databázi.
  • Určuje, zda sloupec existuje v tabulce.
  • Kolik řádků existuje ve sloupci pro hodnotu v daném sloupci.

Tyto funkce jsou určené jako jednoduché, takže se můžete zaměřit na podrobnosti testování částí v tomto článku, nikoli na samotné funkce.

Aby funkce získala nejlepší výsledky testování jednotek, měla by vrátit jeden předvídatelný výsledek a být jedním datovým typem. Pokud chcete například zkontrolovat, jestli něco existuje, měla by funkce vrátit logickou hodnotu true nebo false. Pokud chcete vrátit počet řádků, které existují, měla by funkce vrátit nezáporné celé číslo. V prvním příkladu by nemělo vracet hodnotu false, pokud něco neexistuje, nebo samotnou věc, pokud existuje. Podobně by v druhém příkladu nemělo vracet ani počet řádků, které existují, nebo nepravda, pokud neexistují žádné řádky.

Tyto funkce můžete přidat do existujícího pracovního prostoru Azure Databricks následujícím způsobem v Pythonu, R, Scala nebo SQL.

Python

Následující kód předpokládá, že máte nastavené složky Gitu (Úložiště) Databricks, přidali úložiště a úložiště máte otevřené v pracovním prostoru Azure Databricks.

Vytvořte soubor s názvem myfunctions.py v úložišti a přidejte do něj následující obsah. Další příklady v tomto článku očekávají, že tento soubor bude pojmenován myfunctions.py. Pro vlastní soubory můžete použít různé názvy.

import pyspark
from pyspark.sql import SparkSession
from pyspark.sql.functions import col

# Because this file is not a Databricks notebook, you
# must create a Spark session. Databricks notebooks
# create a Spark session for you by default.
spark = SparkSession.builder \
                    .appName('integrity-tests') \
                    .getOrCreate()

# Does the specified table exist in the specified database?
def tableExists(tableName, dbName):
  return spark.catalog.tableExists(f"{dbName}.{tableName}")

# Does the specified column exist in the given DataFrame?
def columnExists(dataFrame, columnName):
  if columnName in dataFrame.columns:
    return True
  else:
    return False

# How many rows are there for the specified value in the specified column
# in the given DataFrame?
def numRowsInColumnForValue(dataFrame, columnName, columnValue):
  df = dataFrame.filter(col(columnName) == columnValue)

  return df.count()

R

Následující kód předpokládá, že máte nastavené složky Gitu (Úložiště) Databricks, přidali úložiště a úložiště máte otevřené v pracovním prostoru Azure Databricks.

Vytvořte soubor s názvem myfunctions.r v úložišti a přidejte do něj následující obsah. Další příklady v tomto článku očekávají, že tento soubor bude pojmenován myfunctions.r. Pro vlastní soubory můžete použít různé názvy.

library(SparkR)

# Does the specified table exist in the specified database?
table_exists <- function(table_name, db_name) {
  tableExists(paste(db_name, ".", table_name, sep = ""))
}

# Does the specified column exist in the given DataFrame?
column_exists <- function(dataframe, column_name) {
  column_name %in% colnames(dataframe)
}

# How many rows are there for the specified value in the specified column
# in the given DataFrame?
num_rows_in_column_for_value <- function(dataframe, column_name, column_value) {
  df = filter(dataframe, dataframe[[column_name]] == column_value)

  count(df)
}

Scala

Vytvořte poznámkový blok Scala s názvem myfunctions s následujícím obsahem. Další příklady v tomto článku očekávají, že tento poznámkový blok bude pojmenován myfunctions. Pro vlastní poznámkové bloky můžete použít různé názvy.

import org.apache.spark.sql.DataFrame
import org.apache.spark.sql.functions.col

// Does the specified table exist in the specified database?
def tableExists(tableName: String, dbName: String) : Boolean = {
  return spark.catalog.tableExists(dbName + "." + tableName)
}

// Does the specified column exist in the given DataFrame?
def columnExists(dataFrame: DataFrame, columnName: String) : Boolean = {
  val nameOfColumn = null

  for(nameOfColumn <- dataFrame.columns) {
    if (nameOfColumn == columnName) {
      return true
    }
  }

  return false
}

// How many rows are there for the specified value in the specified column
// in the given DataFrame?
def numRowsInColumnForValue(dataFrame: DataFrame, columnName: String, columnValue: String) : Long = {
  val df = dataFrame.filter(col(columnName) === columnValue)

  return df.count()
}

SQL

Následující kód předpokládá, že máte diamanty ukázkových datových sad třetích stran v rámci schématu pojmenovaného default v katalogumain, který je přístupný z pracovního prostoru Azure Databricks. Pokud má katalog nebo schéma, které chcete použít, jiný název, změňte jeden nebo oba následující USE příkazy tak, aby odpovídaly.

Vytvořte poznámkový blok SQL a přidejte do něj následující obsah. Potom poznámkový blok připojte ke clusteru a spuštěním poznámkového bloku přidejte do zadaného katalogu a schématu následující funkce definované uživatelem SQL.

Poznámka:

Funkce definované uživatelem table_exists SQL a column_exists pracují pouze s katalogem Unity. Podpora uživatelem definovaného uživatelem SQL pro Katalog Unity je ve verzi Public Preview.

USE CATALOG main;
USE SCHEMA default;

CREATE OR REPLACE FUNCTION table_exists(catalog_name STRING,
                                        db_name      STRING,
                                        table_name   STRING)
  RETURNS BOOLEAN
  RETURN if(
    (SELECT count(*) FROM system.information_schema.tables
     WHERE table_catalog = table_exists.catalog_name
       AND table_schema  = table_exists.db_name
       AND table_name    = table_exists.table_name) > 0,
    true,
    false
  );

CREATE OR REPLACE FUNCTION column_exists(catalog_name STRING,
                                         db_name      STRING,
                                         table_name   STRING,
                                         column_name  STRING)
  RETURNS BOOLEAN
  RETURN if(
    (SELECT count(*) FROM system.information_schema.columns
     WHERE table_catalog = column_exists.catalog_name
       AND table_schema  = column_exists.db_name
       AND table_name    = column_exists.table_name
       AND column_name   = column_exists.column_name) > 0,
    true,
    false
  );

CREATE OR REPLACE FUNCTION num_rows_for_clarity_in_diamonds(clarity_value STRING)
  RETURNS BIGINT
  RETURN SELECT count(*)
         FROM main.default.diamonds
         WHERE clarity = clarity_value

Volání funkcí

Tato část popisuje kód, který volá předchozí funkce. Pomocí těchto funkcí můžete například spočítat počet řádků v tabulce, ve kterých v rámci specifikovaného sloupce existuje zadaná hodnota. Než ale budete pokračovat, měli byste zkontrolovat, jestli tabulka skutečně existuje a zda sloupec v této tabulce skutečně existuje. Následující kód kontroluje tyto podmínky.

Pokud jste do pracovního prostoru Azure Databricks přidali funkce z předchozí části, můžete tyto funkce volat z pracovního prostoru následujícím způsobem.

Python

Vytvořte poznámkový blok Pythonu ve stejné složce jako předchozí myfunctions.py soubor v úložišti a přidejte do poznámkového bloku následující obsah. Podle potřeby změňte hodnoty proměnných pro název tabulky, název schématu (databáze), název sloupce a hodnotu sloupce. Potom poznámkový blok připojte ke clusteru a spusťte poznámkový blok, aby se zobrazily výsledky.

from myfunctions import *

tableName   = "diamonds"
dbName      = "default"
columnName  = "clarity"
columnValue = "VVS2"

# If the table exists in the specified database...
if tableExists(tableName, dbName):

  df = spark.sql(f"SELECT * FROM {dbName}.{tableName}")

  # And the specified column exists in that table...
  if columnExists(df, columnName):
    # Then report the number of rows for the specified value in that column.
    numRows = numRowsInColumnForValue(df, columnName, columnValue)

    print(f"There are {numRows} rows in '{tableName}' where '{columnName}' equals '{columnValue}'.")
  else:
    print(f"Column '{columnName}' does not exist in table '{tableName}' in schema (database) '{dbName}'.")
else:
  print(f"Table '{tableName}' does not exist in schema (database) '{dbName}'.") 

R

Vytvořte poznámkový blok R ve stejné složce jako předchozí myfunctions.r soubor v úložišti a přidejte do poznámkového bloku následující obsah. Podle potřeby změňte hodnoty proměnných pro název tabulky, název schématu (databáze), název sloupce a hodnotu sloupce. Potom poznámkový blok připojte ke clusteru a spusťte poznámkový blok, aby se zobrazily výsledky.

library(SparkR)
source("myfunctions.r")

table_name   <- "diamonds"
db_name      <- "default"
column_name  <- "clarity"
column_value <- "VVS2"

# If the table exists in the specified database...
if (table_exists(table_name, db_name)) {

  df = sql(paste("SELECT * FROM ", db_name, ".", table_name, sep = ""))

  # And the specified column exists in that table...
  if (column_exists(df, column_name)) {
    # Then report the number of rows for the specified value in that column.
    num_rows = num_rows_in_column_for_value(df, column_name, column_value)

    print(paste("There are ", num_rows, " rows in table '", table_name, "' where '", column_name, "' equals '", column_value, "'.", sep = "")) 
  } else {
    print(paste("Column '", column_name, "' does not exist in table '", table_name, "' in schema (database) '", db_name, "'.", sep = ""))
  }

} else {
  print(paste("Table '", table_name, "' does not exist in schema (database) '", db_name, "'.", sep = ""))
}

Scala

Vytvořte další poznámkový blok Scala ve stejné složce jako předchozí myfunctions poznámkový blok Scala a do tohoto nového poznámkového bloku přidejte následující obsah.

Do první buňky tohoto nového poznámkového bloku přidejte následující kód, který volá magic %run . Díky tomuto kouzlu bude obsah poznámkového myfunctions bloku dostupný pro nový poznámkový blok.

%run ./myfunctions

Do druhé buňky tohoto nového poznámkového bloku přidejte následující kód. Podle potřeby změňte hodnoty proměnných pro název tabulky, název schématu (databáze), název sloupce a hodnotu sloupce. Potom poznámkový blok připojte ke clusteru a spusťte poznámkový blok, aby se zobrazily výsledky.

val tableName   = "diamonds"
val dbName      = "default"
val columnName  = "clarity"
val columnValue = "VVS2"

// If the table exists in the specified database...
if (tableExists(tableName, dbName)) {

  val df = spark.sql("SELECT * FROM " + dbName + "." + tableName)

  // And the specified column exists in that table...
  if (columnExists(df, columnName)) {
    // Then report the number of rows for the specified value in that column.
    val numRows = numRowsInColumnForValue(df, columnName, columnValue)

    println("There are " + numRows + " rows in '" + tableName + "' where '" + columnName + "' equals '" + columnValue + "'.")
  } else {
    println("Column '" + columnName + "' does not exist in table '" + tableName + "' in database '" + dbName + "'.")
  }

} else {
  println("Table '" + tableName + "' does not exist in database '" + dbName + "'.")
}

SQL

Do nové buňky v předchozím poznámkovém bloku nebo do buňky v samostatném poznámkovém bloku přidejte následující kód. V případě potřeby změňte názvy schématu nebo katalogu tak, aby odpovídaly vašemu schématu, a pak spusťte tuto buňku, aby se zobrazily výsledky.

SELECT CASE
-- If the table exists in the specified catalog and schema...
WHEN
  table_exists("main", "default", "diamonds")
THEN
  -- And the specified column exists in that table...
  (SELECT CASE
   WHEN
     column_exists("main", "default", "diamonds", "clarity")
   THEN
     -- Then report the number of rows for the specified value in that column.
     printf("There are %d rows in table 'main.default.diamonds' where 'clarity' equals 'VVS2'.",
            num_rows_for_clarity_in_diamonds("VVS2"))
   ELSE
     printf("Column 'clarity' does not exist in table 'main.default.diamonds'.")
   END)
ELSE
  printf("Table 'main.default.diamonds' does not exist.")
END

Zápis testů jednotek

Tato část popisuje kód, který testuje jednotlivé funkce popsané na začátku tohoto článku. Pokud v budoucnu provedete nějaké změny funkcí, můžete pomocí testů jednotek určit, jestli tyto funkce stále fungují podle očekávání.

Pokud jste do pracovního prostoru Azure Databricks přidali funkce na začátek tohoto článku, můžete do pracovního prostoru přidat testy jednotek pro tyto funkce následujícím způsobem.

Python

Vytvořte další soubor s názvem test_myfunctions.py ve stejné složce jako předchozí myfunctions.py soubor v úložišti a přidejte do něj následující obsah. Ve výchozím nastavení hledá soubory, pytest jejichž názvy začínají test_ (nebo končí_test) k otestování..py Podobně ve výchozím nastavení hledá uvnitř těchto souborů funkce, pytest jejichž názvy začínají testem test_ .

Obecně se doporučuje nespouštět testy jednotek s funkcemi, které pracují s daty v produkčním prostředí. To je zvlášť důležité pro funkce, které přidávají, odebírat nebo jinak měnit data. Pokud chcete chránit produkční data před neočekávanými testy jednotek, měli byste spouštět testy jednotek proti neprodukčním datům. Jedním z běžných přístupů je vytvoření falešných dat, která jsou co nejblíže produkčním datům. Následující příklad kódu vytvoří falešná data pro testy jednotek ke spuštění proti.

import pytest
import pyspark
from myfunctions import *
from pyspark.sql import SparkSession
from pyspark.sql.types import StructType, StructField, IntegerType, FloatType, StringType

tableName    = "diamonds"
dbName       = "default"
columnName   = "clarity"
columnValue  = "SI2"

# Because this file is not a Databricks notebook, you
# must create a Spark session. Databricks notebooks
# create a Spark session for you by default.
spark = SparkSession.builder \
                    .appName('integrity-tests') \
                    .getOrCreate()

# Create fake data for the unit tests to run against.
# In general, it is a best practice to not run unit tests
# against functions that work with data in production.
schema = StructType([ \
  StructField("_c0",     IntegerType(), True), \
  StructField("carat",   FloatType(),   True), \
  StructField("cut",     StringType(),  True), \
  StructField("color",   StringType(),  True), \
  StructField("clarity", StringType(),  True), \
  StructField("depth",   FloatType(),   True), \
  StructField("table",   IntegerType(), True), \
  StructField("price",   IntegerType(), True), \
  StructField("x",       FloatType(),   True), \
  StructField("y",       FloatType(),   True), \
  StructField("z",       FloatType(),   True), \
])

data = [ (1, 0.23, "Ideal",   "E", "SI2", 61.5, 55, 326, 3.95, 3.98, 2.43 ), \
         (2, 0.21, "Premium", "E", "SI1", 59.8, 61, 326, 3.89, 3.84, 2.31 ) ]

df = spark.createDataFrame(data, schema)

# Does the table exist?
def test_tableExists():
  assert tableExists(tableName, dbName) is True

# Does the column exist?
def test_columnExists():
  assert columnExists(df, columnName) is True

# Is there at least one row for the value in the specified column?
def test_numRowsInColumnForValue():
  assert numRowsInColumnForValue(df, columnName, columnValue) > 0

R

Vytvořte další soubor s názvem test_myfunctions.r ve stejné složce jako předchozí myfunctions.r soubor v úložišti a přidejte do něj následující obsah. Ve výchozím nastavení hledá .r soubory, testthat jejichž názvy začínají test testem.

Obecně se doporučuje nespouštět testy jednotek s funkcemi, které pracují s daty v produkčním prostředí. To je zvlášť důležité pro funkce, které přidávají, odebírat nebo jinak měnit data. Pokud chcete chránit produkční data před neočekávanými testy jednotek, měli byste spouštět testy jednotek proti neprodukčním datům. Jedním z běžných přístupů je vytvoření falešných dat, která jsou co nejblíže produkčním datům. Následující příklad kódu vytvoří falešná data pro testy jednotek ke spuštění proti.

library(testthat)
source("myfunctions.r")

table_name   <- "diamonds"
db_name      <- "default"
column_name  <- "clarity"
column_value <- "SI2"

# Create fake data for the unit tests to run against.
# In general, it is a best practice to not run unit tests
# against functions that work with data in production.
schema <- structType(
  structField("_c0",     "integer"),
  structField("carat",   "float"),
  structField("cut",     "string"),
  structField("color",   "string"),
  structField("clarity", "string"),
  structField("depth",   "float"),
  structField("table",   "integer"),
  structField("price",   "integer"),
  structField("x",       "float"),
  structField("y",       "float"),
  structField("z",       "float"))

data <- list(list(as.integer(1), 0.23, "Ideal",   "E", "SI2", 61.5, as.integer(55), as.integer(326), 3.95, 3.98, 2.43),
             list(as.integer(2), 0.21, "Premium", "E", "SI1", 59.8, as.integer(61), as.integer(326), 3.89, 3.84, 2.31))

df <- createDataFrame(data, schema)

# Does the table exist?
test_that ("The table exists.", {
  expect_true(table_exists(table_name, db_name))
})

# Does the column exist?
test_that ("The column exists in the table.", {
  expect_true(column_exists(df, column_name))
})

# Is there at least one row for the value in the specified column?
test_that ("There is at least one row in the query result.", {
  expect_true(num_rows_in_column_for_value(df, column_name, column_value) > 0)
})

Scala

Vytvořte další poznámkový blok Scala ve stejné složce jako předchozí myfunctions poznámkový blok Scala a do tohoto nového poznámkového bloku přidejte následující obsah.

Do první buňky nového poznámkového bloku přidejte následující kód, který volá magii %run . Díky tomuto kouzlu bude obsah poznámkového myfunctions bloku dostupný pro nový poznámkový blok.

%run ./myfunctions

Do druhé buňky přidejte následující kód. Tento kód definuje testy jednotek a určuje, jak je spustit.

Obecně se doporučuje nespouštět testy jednotek s funkcemi, které pracují s daty v produkčním prostředí. To je zvlášť důležité pro funkce, které přidávají, odebírat nebo jinak měnit data. Pokud chcete chránit produkční data před neočekávanými testy jednotek, měli byste spouštět testy jednotek proti neprodukčním datům. Jedním z běžných přístupů je vytvoření falešných dat, která jsou co nejblíže produkčním datům. Následující příklad kódu vytvoří falešná data pro testy jednotek ke spuštění proti.

import org.scalatest._
import org.apache.spark.sql.types.{StructType, StructField, IntegerType, FloatType, StringType}
import scala.collection.JavaConverters._

class DataTests extends AsyncFunSuite {

  val tableName   = "diamonds"
  val dbName      = "default"
  val columnName  = "clarity"
  val columnValue = "SI2"

  // Create fake data for the unit tests to run against.
  // In general, it is a best practice to not run unit tests
  // against functions that work with data in production.
  val schema = StructType(Array(
                 StructField("_c0",     IntegerType),
                 StructField("carat",   FloatType),
                 StructField("cut",     StringType),
                 StructField("color",   StringType),
                 StructField("clarity", StringType),
                 StructField("depth",   FloatType),
                 StructField("table",   IntegerType),
                 StructField("price",   IntegerType),
                 StructField("x",       FloatType),
                 StructField("y",       FloatType),
                 StructField("z",       FloatType)
               ))

  val data = Seq(
                  Row(1, 0.23, "Ideal",   "E", "SI2", 61.5, 55, 326, 3.95, 3.98, 2.43),
                  Row(2, 0.21, "Premium", "E", "SI1", 59.8, 61, 326, 3.89, 3.84, 2.31)
                ).asJava

  val df = spark.createDataFrame(data, schema)

  // Does the table exist?
  test("The table exists") {
    assert(tableExists(tableName, dbName) == true)
  }

  // Does the column exist?
  test("The column exists") {
    assert(columnExists(df, columnName) == true)
  }

  // Is there at least one row for the value in the specified column?
  test("There is at least one matching row") {
    assert(numRowsInColumnForValue(df, columnName, columnValue) > 0)
  }
}

nocolor.nodurations.nostacks.stats.run(new DataTests)

Poznámka:

Tento příklad kódu používá FunSuite styl testování v jazyce ScalaTest. Další dostupné styly testování najdete v tématu Výběr stylů testování pro váš projekt.

SQL

Než přidáte testy jednotek, měli byste mít na paměti, že obecně se doporučuje nespouštět testy jednotek s funkcemi, které pracují s daty v produkčním prostředí. To je zvlášť důležité pro funkce, které přidávají, odebírat nebo jinak měnit data. Pokud chcete chránit produkční data před neočekávanými testy jednotek, měli byste spouštět testy jednotek proti neprodukčním datům. Jedním z běžných přístupů je spouštění testů jednotek na zobrazeních místo tabulek.

Pokud chcete vytvořit zobrazení, můžete volat příkaz CREATE VIEW z nové buňky v předchozím poznámkovém bloku nebo samostatném poznámkovém bloku. Následující příklad předpokládá, že máte existující tabulku pojmenovanou diamonds ve schématu (databázi) pojmenovanou default v katalogu s názvem main. Podle potřeby změňte tyto názvy tak, aby odpovídaly vašemu vlastnímu názvu, a pak spusťte pouze tuto buňku.

USE CATALOG main;
USE SCHEMA default;

CREATE VIEW view_diamonds AS
SELECT * FROM diamonds;

Po vytvoření zobrazení přidejte každý z následujících SELECT příkazů do vlastní nové buňky v předchozím poznámkovém bloku nebo do vlastní nové buňky v samostatném poznámkovém bloku. Podle potřeby změňte názvy tak, aby odpovídaly vašemu vlastnímu.

SELECT if(table_exists("main", "default", "view_diamonds"),
          printf("PASS: The table 'main.default.view_diamonds' exists."),
          printf("FAIL: The table 'main.default.view_diamonds' does not exist."));

SELECT if(column_exists("main", "default", "view_diamonds", "clarity"),
          printf("PASS: The column 'clarity' exists in the table 'main.default.view_diamonds'."),
          printf("FAIL: The column 'clarity' does not exists in the table 'main.default.view_diamonds'."));

SELECT if(num_rows_for_clarity_in_diamonds("VVS2") > 0,
          printf("PASS: The table 'main.default.view_diamonds' has at least one row where the column 'clarity' equals 'VVS2'."),
          printf("FAIL: The table 'main.default.view_diamonds' does not have at least one row where the column 'clarity' equals 'VVS2'."));

Spuštění testů jednotek

Tato část popisuje, jak spustit testy jednotek, které jste naprogramovali v předchozí části. Když spustíte testy jednotek, zobrazí se výsledky, které testy jednotek proběhly a které selhaly.

Pokud jste do pracovního prostoru Azure Databricks přidali testy jednotek z předchozí části, můžete tyto testy jednotek spustit z pracovního prostoru. Tyto testy jednotek můžete spouštět ručně nebo podle plánu.

Python

Vytvořte poznámkový blok Pythonu ve stejné složce jako předchozí test_myfunctions.py soubor v úložišti a přidejte následující obsah.

Do první buňky nového poznámkového bloku přidejte následující kód a spusťte buňku, která volá magii %pip . Tato magic nainstaluje pytest.

%pip install pytest

Do druhé buňky přidejte následující kód a pak buňku spusťte. Výsledky ukazují, které testy jednotek prošly a selhaly.

import pytest
import sys

# Skip writing pyc files on a readonly filesystem.
sys.dont_write_bytecode = True

# Run pytest.
retcode = pytest.main([".", "-v", "-p", "no:cacheprovider"])

# Fail the cell execution if there are any test failures.
assert retcode == 0, "The pytest invocation failed. See the log for details."

R

Vytvořte poznámkový blok R ve stejné složce jako předchozí test_myfunctions.r soubor v úložišti a přidejte následující obsah.

Do první buňky přidejte následující kód a spusťte buňku install.packages , která volá funkci. Tato funkce nainstaluje testthat.

install.packages("testthat")

Do druhé buňky přidejte následující kód a pak buňku spusťte. Výsledky ukazují, které testy jednotek prošly a selhaly.

library(testthat)
source("myfunctions.r")

test_dir(".", reporter = "tap")

Scala

Spusťte první a druhou buňky v poznámkovém bloku z předchozí části. Výsledky ukazují, které testy jednotek prošly a selhaly.

SQL

Spusťte všechny tři buňky v poznámkovém bloku z předchozí části. Výsledky ukazují, jestli byl každý test jednotek úspěšný nebo neúspěšný.

Pokud už zobrazení po spuštění testů jednotek nepotřebujete, můžete zobrazení odstranit. Pokud chcete toto zobrazení odstranit, můžete do nové buňky v jednom z předchozích poznámkových bloků přidat následující kód a pak spustit jenom tuto buňku.

DROP VIEW view_diamonds;

Tip

Výsledky spuštění poznámkového bloku (včetně výsledků testů jednotek) můžete zobrazit v protokolech ovladačů clusteru. Můžete také zadat umístění pro doručování protokolů vašeho clusteru.

Můžete nastavit systém kontinuální integrace a průběžného doručování nebo nasazování (CI/CD), jako je GitHub Actions, a automaticky spouštět testy jednotek při každé změně kódu. Podívejte se například na pokrytí GitHub Actions v osvědčených postupech pro softwarové inženýrství pro poznámkové bloky.

Další materiály

pytest

testthat

ScalaTest

SQL