处理单元测试过程

注释

此内容适用于 Visual Studio 中的旧版 Power Query SDK。 今天,Visual Studio Code 中的新 Power Query SDK 包含一个功能齐全的 测试框架 ,我们鼓励你测试和了解详细信息。

对于简单和复杂的连接器,添加单元测试是最佳做法,强烈建议这样做。

单元测试是在 Visual Studio 的 Power Query SDK 的上下文中完成的。 每个测试都定义为 Fact 名称、预期值和实际值。 在大多数情况下,“实际值”是一个 M 表达式,用于测试表达式的一部分。

请考虑导出三个函数的扩展:

section Unittesting;

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

此单元测试代码由许多事实组成,以及单元测试框架(ValueToText、、 FactFactsFacts.Summarize的一堆常见代码。 以下代码提供了一组事实示例(转到 UnitTesting.query.pq 以获取常见代码):

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];

在 Visual Studio 中运行示例会评估所有事实,并提供传递率的直观摘要:

Visual Studio M 查询输出的屏幕截图,其中显示了传递率示例。

在连接器开发过程中尽早实施单元测试,可以遵循测试驱动开发的原则。 假设需要编写一个只从 URI 返回主机数据的函数 Uri.GetHost 。 首先编写测试用例来验证函数是否适当地执行预期函数:

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")
)

可以编写更多测试,以确保函数适当地处理边缘事例。

函数的早期版本可能通过一些但并非所有测试:

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

Visual Studio M 查询输出的屏幕截图,其中某些测试失败。

函数的最终版本应通过所有单元测试。 此版本还可轻松确保函数的未来更新不会意外删除其任何基本功能。

Visual Studio M 查询输出的屏幕截图,其中所有测试都通过。