Java 不产生不同输出的单元测试方法

Java 不产生不同输出的单元测试方法,java,unit-testing,vaadin,Java,Unit Testing,Vaadin,在我的vaadingui应用程序中,有许多方法如下所示 @Override protected void loadLayout() { CssLayout statusLayout = new CssLayout(); statusLayout.addComponent(connectedTextLabel); statusLayout.addComponent(connectedCountLabel); statusLayout.addComponent(no

在我的vaadingui应用程序中,有许多方法如下所示

@Override
protected void loadLayout() {
    CssLayout statusLayout = new CssLayout();

    statusLayout.addComponent(connectedTextLabel);
    statusLayout.addComponent(connectedCountLabel);
    statusLayout.addComponent(notConnectedTextLabel);
    statusLayout.addComponent(notConnectedCountLabel);

    connectionsTable.getCustomHeaderLayout().addComponent(statusLayout);
    connectionsTable.getCustomHeaderLayout().addComponent(commandLayout);
    connectionsTable.getCustomHeaderLayout().addComponent(historyViewCheckbox);

    bodySplitter.addComponent(connectionsTable);
    bodySplitter.addComponent(connectionHistoryTable);
    bodySplitter.setSplitPosition(75, Sizeable.Unit.PERCENTAGE);
    bodySplitter.setSizeFull();
    bodyLayout.addComponent(bodySplitter);

    if (connectionDef.getConnectionHistoryDef() == null) {
        historyViewCheckbox.setVisible(false);
    }
    if (connectionDef.getConnectionStatusField() == null || connectionDef.getConnectedStatusValue() == null || connectionDef.getConnectedStatusValue().isEmpty()) {
        connectedTextLabel.setVisible(false);
        connectedCountLabel.setVisible(false);
        notConnectedTextLabel.setVisible(false);
        notConnectedCountLabel.setVisible(false);
    }
}


protected void setStyleNamesAndControlIds() {
    mainLayout.setId("mainLayout");
    header.setId("header");
    footer.setId("footer");
    propertyEditorLayout.setId("propertyEditorLayout");
    propertyEditor.setId("propertyEditor");

    mainLayout.setStyleName("mainLayout");
    propertyEditorLayout.setStyleName("ui_action_edit");
    header.setStyleName("TopPane");
    footer.setStyleName("footer");
}
这些方法用于设置GUI的布局。它们不会产生单一的不同输出。这些方法中的几乎每一行都在做单独的工作,这与其他行几乎无关

通常,在对方法进行单元测试时,我会检查方法的返回值,或者验证对有限数量的外部对象(如数据库连接)的调用

但是,对于上述方法,没有这样的单一输出。如果我为这些方法编写单元测试,我的测试代码将检查方法中每一行中发生的每个方法调用,最后,它看起来几乎像方法本身

如果有人以任何方式更改了代码,测试将中断,他们将不得不更新测试以匹配更改。但是,由于测试没有检查在浏览器中绘制的实际UI,所以不能保证更改实际上没有破坏任何东西

例如,如果有人更改了控件的样式名,他必须用新的样式名更新测试代码,测试将通过。但是,为了使事情能够正常工作,他还必须更改相关的scss样式文件。但这项测试对检测这个问题没有任何帮助。布局设置代码也同样适用

除了将代码覆盖率保持在更高的级别之外,编写上述单元测试还有什么好处吗?对我来说,编写一个测试来比较该方法的反编译字节码和作为字符串保存在测试中的原始反编译字节码似乎比这类测试要好得多,这让我觉得没用

像上面这样编写单元测试除了 将代码覆盖率保持在更高的级别

是的,如果你采取明智的方法。正如您所说,测试控件是否具有特定样式可能没有意义。因此,将测试重点放在代码中可能出现故障的部分。如果有任何条件逻辑用于生成UI,请测试该逻辑。然后,测试将保护您的代码不受将来可能破坏逻辑的更改的影响

至于您对不返回值的测试方法的评论,您可以通过几种方式来解决

  • 这是您的代码,因此您可以重新构造它,使其更易于测试。考虑将其分解为更小的方法。将逻辑隔离到可以在测试中调用的各个方法中
  • 间接验证—不要关注返回值,而是关注方法对系统中其他对象的影响
  • 最后,考虑UI的单元测试是否适合您和您的组织。UI通常很难进行单元测试(正如您所指出的)。许多公司为他们的UI编写功能测试。这些测试驱动实际产品的UI。这与单元测试非常不同,单元测试不需要完整的产品,只针对非常小的功能单元

    像上面这样编写单元测试除了 将代码覆盖率保持在更高的级别

    是的,如果你采取明智的方法。正如您所说,测试控件是否具有特定样式可能没有意义。因此,将测试重点放在代码中可能出现故障的部分。如果有任何条件逻辑用于生成UI,请测试该逻辑。然后,测试将保护您的代码不受将来可能破坏逻辑的更改的影响

    至于您对不返回值的测试方法的评论,您可以通过几种方式来解决

  • 这是您的代码,因此您可以重新构造它,使其更易于测试。考虑将其分解为更小的方法。将逻辑隔离到可以在测试中调用的各个方法中
  • 间接验证—不要关注返回值,而是关注方法对系统中其他对象的影响

  • 最后,考虑UI的单元测试是否适合您和您的组织。UI通常很难进行单元测试(正如您所指出的)。许多公司为他们的UI编写功能测试。这些测试驱动实际产品的UI。这与单元测试非常不同,单元测试不需要完整的产品,只针对非常小的功能单元。

    下面是一个简单的示例,您可以看看如何浏览应用程序并尝试所需的内容。这是vaadin 8、CDI和Wildfly Swarm示例,绝不是测试vaadin应用程序UI的唯一方法


    这里有一个简单的例子,您可以看看如何浏览应用程序并尝试所需内容。这是vaadin 8、CDI和Wildfly Swarm示例,绝不是测试vaadin应用程序UI的唯一方法


    难道没有办法将应用程序编译成html/javascript吗?如果是这样,那么您可以这样做并测试生成的输出…不知何故。我不熟悉Vaadininho,你不能用这种方法编写一个好的测试,因为它不遵循SRP原则。我建议您将测试方法改为在实际前端进行自动化测试的框架,如Selenium或TestingWhiz或其他类似的测试。下面是一些刚刚搜索的测试方法的列表,我发现了以下问题:。你可能需要在这里重新设计,但我认为这基本上是它应该的。每个组件都应该是可测试的,因此您只需确定要测试的组件,并为每个组件创建一个简单的junit测试类难道没有办法将应用程序编译为html/javascript吗?如果是这样,那么您可以这样做并测试生成的输出…不知何故。我不熟悉Vaadininho,你不能用这种方法编写一个好的测试,因为它不遵循SRP原则。我建议您将测试方法更改为在实际前端(如Selenium或TestingWhiz)进行自动化测试的框架