【问题标题】:How do I do test-driven development using Vaadin?如何使用 Vaadin 进行测试驱动开发?
【发布时间】:2011-11-23 04:44:42
【问题描述】:

构建基于 Vaadin 的应用程序以便我可以使用 TDD(测试驱动开发)来创建应用程序的最佳方法是什么?换句话说,我不想编写需要服务器或浏览器(甚至它们的模拟器)的测试,因为它们可能太脆弱、太慢或两者兼而有之。

Translating GWT MVP Pattern to Vaadin 的问题有点相关,因为我正在寻找正确的模式以使我的 UI“逻辑”尽可能可测试,但我不确定 MVP 是否适用于 Vaadin。

【问题讨论】:

    标签: java gwt tdd vaadin


    【解决方案1】:

    查看Model View Presenter 模式,也称为“谦虚视图”。

    如果操作正确,视图是唯一您无法测试的对象,并且由于它不包含任何逻辑,您根本不必费心对其进行测试。

    【讨论】:

    【解决方案2】:

    我才刚刚开始使用 Vaadin,并且“我可以使用 Vaadin 进行 TDD 吗?”是我首先考虑的。我发现(到目前为止)实际上很容易。虽然我最终写了很多代码。

    我要做的第一件事就是编写一些工厂类。这样我就可以将模拟 UI 对象注入到我的类中。例如:

    public class ButtonFactory {
    
        public Button create() {
            return new Button();
        }
    
        public Button create(String caption) {
             return new Button(caption);
        }
    
        public Button create(String caption, Button.ClickListener listener) {
             return new Button(caption, listener);
        }
    }
    

    然后我为我需要的主要 UI 组件创建了工厂:

    @ApplicationScoped
    public class SiteAdminButtonBarFactory implements Serializable {
    
        private static final long serialVersionUID = -462493589568567794L;
    
        private ButtonFactory buttonFactory = null;
        private HorizontalLayoutFactory horizontalLayoutFactory = null;
    
        public SiteAdminButtonBarFactory() {}
    
        @Inject
        public SiteAdminButtonBarFactory(HorizontalLayoutFactory horizontalLayoutFactory, ButtonFactory buttonFactory) {
            this.horizontalLayoutFactory = horizontalLayoutFactory;
            this.buttonFactory = buttonFactory;
        }
    
        public SiteAdminButtonBar create() {
            HorizontalLayout layout = horizontalLayoutFactory.create();
    
            layout.addComponent(addButton());
            layout.addComponent(removeButton());
            layout.addComponent(editButton());
    
            return new SiteAdminButtonBar(layout);
        }
    
        private Button addButton() {
            return buttonFactory.create("Add");
        }
    
        private Button removeButton() {
            return buttonFactory.create("Remove");
        }
    
        private Button editButton() {
            return buttonFactory.create("Edit");
        }
    }
    

    相关的测试代码是:

    public class SiteAdminButtonBarFactoryTest {
    
        private HorizontalLayout horizontalLayout = null;
        private HorizontalLayoutFactory horizontalLayoutFactory = null;
        private Button addButton = null;
        private Button removeButton = null;
        private Button editButton = null;
        private ButtonFactory buttonFactory = null;
    
        private SiteAdminButtonBarFactory siteAdminButtonBarFactory = null;
    
        @Test
        public void shouldCreateAHorizontalLayout() throws Exception {
            givenWeHaveAFullyConfiguredSiteAdminButtonBarFactory();
    
            SiteAdminButtonBar siteAdminButtonBar = siteAdminButtonBarFactory.create();
    
            assertThat(siteAdminButtonBar, is(notNullValue()));
            verify(horizontalLayoutFactory).create();
        }
    
        @Test
        public void shouldContainAnADDButton() throws Exception {
            givenWeHaveAFullyConfiguredSiteAdminButtonBarFactory();
    
            siteAdminButtonBarFactory.create();
    
            verify(buttonFactory).create("Remove");
            verify(horizontalLayout).addComponent(removeButton);
        }
    
        @Test
        public void shouldContainARemoveButton() throws Exception {
            givenWeHaveAFullyConfiguredSiteAdminButtonBarFactory();
    
            siteAdminButtonBarFactory.create();
    
            verify(buttonFactory).create("Edit");
            verify(horizontalLayout).addComponent(editButton);
        }
    
        @Test
        public void shouldContainAnEditButton() throws Exception {
            givenWeHaveAFullyConfiguredSiteAdminButtonBarFactory();
    
            siteAdminButtonBarFactory.create();
    
            verify(buttonFactory).create("Add");
            verify(horizontalLayout).addComponent(addButton);
        }
    
        private void givenWeHaveAFullyConfiguredSiteAdminButtonBarFactory() {
            horizontalLayout = mock(HorizontalLayout.class);
            horizontalLayoutFactory = mock(HorizontalLayoutFactory.class);
            when(horizontalLayoutFactory.create()).thenReturn(horizontalLayout);
    
            addButton = mock(Button.class);
            removeButton = mock(Button.class);
            editButton = mock(Button.class);
            buttonFactory = mock(ButtonFactory.class);
            when(buttonFactory.create("Add")).thenReturn(addButton);
            when(buttonFactory.create("Remove")).thenReturn(removeButton);
            when(buttonFactory.create("Edit")).thenReturn(editButton);
    
            siteAdminButtonBarFactory = new SiteAdminButtonBarFactory(horizontalLayoutFactory, buttonFactory);
        }
    }
    

    我承认一开始我必须先编写代码,然后再进行测试,直到我弄清楚如何构建事物。此外,我还没有对事件监听器等进行 TDD(你会注意到按钮有标题,但没有动作监听器)。但我快到了!

    【讨论】:

      【解决方案3】:

      一旦 Vaadin 是基于 UI 的 Web 框架,您就可以选择基于验收测试的测试解决方案,例如 Selenium。因此,您仍然可以在您的业务/模型层中使用测试驱动开发,这应该与您的 UI 类完全隔离。

      UI 是您可以触摸的东西,您可以更改它并在修改的那一刻看到它,您可以实时接受行为并使用一些好的工具将其自动化。

      业务/模型是一个关键层,您需要改进 API 设计以便更好地理解并将业务转换为代码。对于任何更改,您都需要确保安全,不要违反您的规则 - 为此,只需使用单元测试(此处完全应用 TDD,但不是强制性的)

      【讨论】:

      • 感谢您的回复,但我正在寻找可以采用的更具体的模式或具体做法。您的回答非常模糊和笼统,因此最终对我没有太大帮助。
      【解决方案4】:

      Model View Presenter 模式实际上是划分 Vaadin 应用程序表示逻辑的好方法和推荐方法。它甚至是官方Advanced Vaadin Training 课程的一部分。 Here is the example 在 Vaadin 中实现 MVP。但是,根据具体应用,可以使用各种版本的 MVP。

      理想状态是可测试的presenter包含尽可能多的逻辑,视图尽可能被动。对于实际视图的测试,最好使用Web Tests从用户的角度进行测试。 Vaadin 为此提供了一个特殊的工具 - Vaadin TestBench,它基于 Selenium Webdriver 并修改为 Vaadin Environment。 TestBench 有some advantages 提供普通硒,例如 vaadin 调整等待 ajax 动作和高级屏幕截图比较。这应该与某种 Selenium Grid 结合使用,例如 SauceLabs,它提供了广泛的操作系统、Web 浏览器及其版本的组合,可用于您的测试。

      请注意,Vaadin TestBench 不是免费的,需要许可证或Vaadin pro subscription

      【讨论】:

        【解决方案5】:

        您可以使用 karibu 测试框架:https://github.com/mvysny/karibu-testing。它允许您使用实际成熟的 Vaadin 组件运行和测试您的应用程序,因此您不必使用 MVP 或自定义组件工厂来构建特殊的 UI 进行测试。请参阅上面的链接,了解如何为您的应用编写和运行 Vaadin 单元测试的具体示例和教程。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-19
          相关资源
          最近更新 更多