Manipulando testes de unidade

Para conectores simples e complexos, adicionar testes de unidade é uma prática recomendada e altamente recomendada.

O teste de unidade é realizado no contexto do SDKVisual Studio do Power Query. Cada teste é definido como um Fact que tem um nome, um valor esperado e um valor real. Na maioria dos casos, o "valor real" será uma expressão M que testa parte da expressão.

Considere uma extensão muito simples que exporta três funções:

section Unittesting;

shared UnitTesting.ReturnsABC = () => "ABC";
shared UnitTesting.Returns123 = () => "123";
shared UnitTesting.ReturnTableWithFiveRows = () => Table.Repeat(#table({"a"},{{1}}),5);

Esse código de teste de unidade é feito de vários Fatos e um monte de código comum para a estrutura de teste de unidade ( ValueToText , Fact , , Facts Facts.Summarize ). O código a seguir fornece um conjunto de fatos de exemplo (consulte UnitTesting.query.pq para o código comum):

section UnitTestingTests;

shared MyExtension.UnitTest = 
[
    // Put any common variables here if you only want them to be evaluated once

    // Fact(<Name of the Test>, <Expected Value>, <Actual Value>)
    facts = 
    {
        Fact("Check that this function returns 'ABC'",  // name of the test
            "ABC",                                      // expected value
            UnitTesting.ReturnsABC()                    // expression to evaluate (let or single statement)
        ),
        Fact("Check that this function returns '123'",
            "123",
            UnitTesting.Returns123()
        ),
        Fact("Result should contain 5 rows",
            5,
            Table.RowCount(UnitTesting.ReturnTableWithFiveRows())
        ),
        Fact("Values should be equal (using a let statement)",
            "Hello World",
            let
                a = "Hello World"
            in
                a
        )
    },
    report = Facts.Summarize(facts)
][report];

Executar o exemplo em Visual Studio avaliará todos os Fatos e lhe dará um resumo visual das taxas de aprovação:

Exemplo de taxas de aprovação.

Implementar o teste de unidade no início do processo de desenvolvimento do conector permite que você siga os princípios do desenvolvimento orientado a testes. Imagine que você precisa escrever uma função chamada Uri.GetHost que retorna apenas os dados do host de um URI. Você pode começar escrevendo um caso de teste para verificar se a função executa adequadamente a função esperada:

Fact("Returns host from URI",
    "https://bing.com",
    Uri.GetHost("https://bing.com/subpath/query?param=1&param2=hello")
),
Fact("Handles port number appropriately",
    "https://bing.com:8080",
    Uri.GetHost("https://bing.com:8080/subpath/query?param=1&param2=hello")
)

Testes adicionais podem ser escritos para garantir que a função lida adequadamente com casos de borda.

Uma versão inicial da função pode passar em alguns testes, mas não em todos:

Uri.GetHost = (url) =>
    let
        parts = Uri.Parts(url)
    in
        parts[Scheme] & "://" & parts[Host]

Alguns testes falham.

A versão final da função deve passar em todos os testes de unidade. Isso também facilita garantir que atualizações futuras para a função não removam acidentalmente nenhuma de suas funcionalidades básicas.

Todos os testes serão aprovados.