处理单元测试

注意

此内容适用于 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);

此单元测试代码由许多事实以及单元测试框架(ValueToTextFactFactsFacts.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 中运行示例,则评估所有事实,并提供通过率的直观摘要:

通过率的示例。

在连接器开发过程中及早实施单元测试,可以遵循测试驱动开发的原则。 假设你需要编写一个只从 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]

某些测试失败。

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

所有测试通过。