[Flutter翻译]Discreet日志#5:用Cwtch UI测试提高安全性

368 阅读5分钟

image.png

原文地址:

原文作者:

发布时间:2021年4月16日

欢迎来到Discreet Log! 这是一个两周一次的技术开发博客,深入介绍我们在Open Privacy从事的研究、项目和工具。在我们的第五篇文章中,Erin Atwater谈到了我们为Cwtch测试的基于Flutter的新UI。


我的上一篇文章中,我讨论了将Cwtch的用户界面从Qt移植到Flutter(使用我们通用的Go后端)。

本周,我将介绍我们使用flutter测试工具来提高新Cwtch用户界面的质量和安全性。

我们将看看Flutter小部件和集成测试,以及我们如何使用它们来测试从我们的自定义文本框到安全关键功能,如 "阻断是否真的有效?"。

Flutter测试

Flutter 测试包提供了您编写和自动化测试所需的大部分内容。例如,这里写了一些基本测试,以测试我们的文本框部件的输入处理和验证,配置为在表单中作为一个必需的整数。

    // Inflate the widget to get its initial appearance
    await tester.pumpWidget(testHarness);
    // Make sure it looks like the screenshot on file
    await expectLater(find.byWidget(testHarness), matchesGoldenFile(file('form_init')));
    // Make sure the placeholder text is correct
    expect(find.text(strLabel1), findsOneWidget);

    // "42" valid integer test
    // focus on the text field
    await tester.tap(find.byWidget(testWidget));
    // advance a frame, type, then advance more frames
    await tester.pump();
    await tester.enterText(find.byWidget(testWidget), "42");
    await tester.pumpAndSettle();
    // make sure the input text is rendering as expected
    await expectLater(find.byWidget(testHarness), matchesGoldenFile(file('form_42')));
    expect(find.text("42"), findsOneWidget);
    // make sure no errors are being displayed
    expect(find.text(strFail1), findsNothing);
    expect(find.text(strFail2), findsNothing);
    // reset state for next test
    ctrlr1.clear();
    await tester.pumpAndSettle();

    // "alpha quadrant" (test rejection for being non-integer)
    await tester.tap(find.byWidget(testWidget));
    await tester.pump();
    await tester.enterText(find.byWidget(testWidget), "alpha quadrant");
    await tester.pumpAndSettle();
    await expectLater(find.byWidget(testHarness), matchesGoldenFile(file('form_alpha')));
    // text is rendered correctly...
    expect(find.text("alpha quadrant"), findsOneWidget);
    expect(find.text(strFail1), findsNothing);
    // ...and so is the appropriate error message
    expect(find.text(strFail2), findsOneWidget);
    ctrlr1.clear();
    await tester.pumpAndSettle();

    // "" empty string rejection test
    // ctrlr1.clear() doesn't trigger validate like keypress does so:
    formKey.currentState.validate();
    await tester.pumpAndSettle();
    await expectLater(find.byWidget(testHarness), matchesGoldenFile(file('form_final')));
    // this time we want a different error message
    expect(find.text(strFail1), findsOneWidget);
    expect(find.text(strFail2), findsNothing);

matchesGoldenFile函数会自动为你创建参考图片(flutter test --update goldens),这非常方便。

image.png

如果后来的回归/bug导致widget以不同的方式呈现,那么这种差异会被直观地检测出来,Flutter test甚至好心地为我们计算一些图像差异,比如在这种情况下,输入-验证-错误的颜色被 "意外地 "设置为绿色。

image.png

集成测试

好了,我们已经验证了textfields是可以容纳文本的字段......你是不是已经坐立不安了?幸运的是,一旦所有的部件测试和单元测试结束,我们还可以用这个相同的包运行Cwtch的基于用户界面的功能(集成)测试,以测试更多有趣和重要的行为。

例如,考虑一个发生在安全/反骚扰功能中的关键错误,如 "阻止 "功能。这里的错误有可能造成破坏性的后果,所以我们想采取额外的措施来确保,例如,在另一个功能上的工作不会意外地导致块功能停止工作。

在测试阻断功能时,至关重要的是,不仅设置窗格上的切换状态会被改变/保存,而且被阻断的联系人的新信息也不应该出现。

幸运的是,使用上述相同的图像差异技术,可以比较容易地检查某些东西是否出现或改变。我们可以用这样的测试来检验接收信息是否有效,以及是否能接收来自被屏蔽的联系人的信息。

    // start the app and render a few frames
    app.main();
    await tester.pump();

    // log in to a profile with a blocked contact
    await tester.tap(find.text(testerProfile));
    await tester.pump();
    expect(find.byIcon(Icons.block), findsOneWidget);

    // use the debug control to inject a message from the contact
    await tester.tap(find.byIcon(Icons.bug_report));
    await tester.pump();


    // screenshot test
    await expectLater(find.byKey(Key('app')), matchesGoldenFile('blockedcontact.png'));
    // any active message badges?
    expect(find.text('1'), findsNothing);

1.gif

如果来自被屏蔽的联系人的消息在到达时引起界面上任何意想不到的视觉变化,这个测试会捕捉到它,并在这个错误进入用户的设备之前提醒我们。

例如,假设我们在测试过程中不小心在被屏蔽的联系人的肖像上显示了一个 "收到的消息 "的计数器徽章;它将会被这样捕捉。

image.png

我是这种测试方式的忠实粉丝。当把这些测试写进管道时,很容易看到它们如何从用户故事中衍生出来,并在未来用于支持它们。

当然,测试用例本身必须最初创建,并由人眼审查和偶尔更新,但像这样的测试至少提供了一个额外的信心,即事情仍然按照我们期望的方式工作。这些测试也与我们的库的自动集成测试协同工作,以充分锻炼相关的代码(我们将在即将到来的Discreet日志中讨论更多关于这个问题)。

代码覆盖率

当运行测试时,添加--覆盖率参数以同时计算代码覆盖率信息是很容易的。这将产生一个名为lcov.info的文件,可以输入lcov或任何其他兼容的可视化工具,产生一个像这样的报告。

image.png

......可以进一步钻研,像这样。

image.png

自动化

由于Dan在构建自动化方面的工作,我们可以让Drone为我们自动运行所有这些测试,并将结果更新到PR中。

image.png

总结

有了这么多伟大的工具可以帮助我们使Cwtch成为一个愉快和安全的体验,我很高兴看到最终的产品,并最终将Cwtch放入Beta版,开始让它进一步走向世界 高质量的工作需要时间和资源;如果你愿意帮助我们开发Cwtch,请考虑捐款


通过www.DeepL.com/Translator(免费版)翻译