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ří:
- Funkce a jejich testy jednotek se ukládají mimo poznámkové bloky.
- Výhody: Tyto funkce můžete volat s poznámkovými bloky i mimo nich. Testovací architektury jsou lépe navržené tak, aby spouštěly testy mimo poznámkové bloky.
- Výzvy: Tento přístup není podporován pro poznámkové bloky Scala. Tento přístup také zvyšuje počet souborů ke sledování a údržbě.
- Funkce můžete ukládat v jednom poznámkovém bloku a jejich testy jednotek v samostatném poznámkovém bloku.
- Výhody: Tyto funkce se snadněji používají napříč poznámkovými bloky.
- Výzvy: Počet poznámkových bloků, které je potřeba sledovat a udržovat, se zvyšuje. Tyto funkce nelze použít mimo poznámkové bloky. Tyto funkce můžou být také obtížnější testovat mimo poznámkové bloky.
- Funkce a jejich testy jednotek můžete ukládat do stejného poznámkového bloku.
- Výhody: Funkce a jejich testy jednotek se ukládají v jednom poznámkovém bloku pro snadnější sledování a údržbu.
- Výzvy: Tyto funkce můžou být obtížnější opakovaně používat v poznámkových blocích. Tyto funkce nelze použít mimo poznámkové bloky. Tyto funkce můžou být také obtížnější testovat mimo poznámkové bloky.
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
- domovská stránka pytestu
- pytest – návody
- Referenční příručky pytestu
- Osvědčené postupy pro softwarové inženýrství pro poznámkové bloky
testthat
ScalaTest
- Domovská stránka ScalaTest
- Uživatelská příručka scalaTest
- Dokumentace k scaladoc společnosti ScalaTest