Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 创建可配置的从属资源 描述_Java_Cucumber_Cucumber Jvm - Fatal编程技术网

Java 创建可配置的从属资源 描述

Java 创建可配置的从属资源 描述,java,cucumber,cucumber-jvm,Java,Cucumber,Cucumber Jvm,目前,我正在为一项服务创建一些Cumber特性。假设我有一个用于配置特斯拉汽车的服务: public class TeslaCar { Engine engine; Color color; // other things here... } 在哪里 简单的create调用很容易实现,我只是使用Given和Add组合来配置资源,然后调用create 因此,对于CreateEngine,我会: Feature: CreateEngine Scenario Outl

目前,我正在为一项服务创建一些Cumber特性。假设我有一个用于配置特斯拉汽车的服务:

public class TeslaCar {
    Engine engine;
    Color color;
    // other things here...
}
在哪里

简单的create调用很容易实现,我只是使用
Given
Add
组合来配置资源,然后调用create

因此,对于
CreateEngine
,我会:

Feature: CreateEngine
    Scenario Outline: Create Engine
        Given an engine was initialized
          And engine has <all_wheel>
          And kwh is <kwh>
        When engine is created
        Then engine creation succeeds

    Examples:
    | kwh | all_wheel |
    | 60  | false     |
    | 60  | true      |
    | 70  | false     |
问题 一开始这似乎很合理,但有更好的方法吗?如果需要为驱动车配置更多的东西,那么它很快就会变得非常笨拙

问题
  • 这是考试的坏习惯吗
  • 有没有更好的方法来实现这一点
  • 我不是在想黄瓜吗
  • 可能的解决方案1? 我想到的一件事是使用
    @tags
    。这会让我说,‘每当我使用
    @60kWh
    ,我都需要一台60kWh发动机’。但这并没有得到很好的推广

    可能的解决方案2?
    不要配置汽车,而是使用默认的。

    我将压缩向汽车添加发动机等部件的步骤。使用
    DataTable
    添加引擎的所有属性。从这个新的步骤定义中,您可以调用发动机设置的现有代码,该定义只将
    DataTable
    作为参数。这样,您就不需要每次添加新属性时都添加新的步骤定义。只需附加到DataTable的末尾

    如果你有一个新的汽车零部件,你只需要在你的特征文件中添加3行,再加上一个步骤定义。例如,我在功能中添加了一个齿轮箱

    如果在功能文件DataTable中,将表头命名为与实例变量相同的名称,则Cucumber将自动将值放入类中,如果您将参数(如
    List engine
    )而不是
    DataTable

    我看到的问题是,如果您有一个具有多个设置的属性。例如,发动机模式可以是城市模式、巡航模式和运动模式。也许您可以使用逗号分隔的字符串,然后将其拆分

    Feature: Drive Car
      Scenario: Test drive Tesla
        Given A car with following components
    
        And Add engine with specifications
          | kwh  | allwheel |
          | P90D | true     |
    
        And Add gearbox with specifications
          | noofgears  | auto |  
          | 4          | true |          
    
        And assemble car
        When car is driven
        Then max speed is 120mph
    

    如果你想要更多的乐趣,考虑一下它是一个场景大纲,测试一个特征中的多个组合。但接下来您将有一个大的示例表,其中包含一行数据。实际上,我会使用这个路由,因为我会从一个场景中获得更多,它会将数据从步骤中推送到示例表中


    功能文件中的步骤似乎是对代码的总结,而不是像初始化引擎这样的步骤。但是,如果每个人都理解它并为您的目的服务,为什么要更改它呢。

    Cucumber是为验收测试而设计的,这些测试按照用户的意愿执行整个系统(因此它们也是集成测试),并且可以被涉众和开发人员理解

    您的
    CreateEngine
    场景并不是针对整个系统,而是针对只对开发人员有意义的软件组件,因此我不会使用Cucumber,而是使用单元测试框架来测试它

    另一方面,您的“驾驶汽车”场景是一个合适的验收测试。不过,它有很多软件细节。我会这样写:

    Feature: Drive Car
    
      Scenario: Test drive Tesla
        Given there is a car with an all-wheel-drive engine and P90D engine kwh
        When the car is driven
        Then the max speed is 120 mph
    
    (我不确定“P90D engine kwh”的语法是否正确,因此请根据需要更正。)

    要点:

    • 没有提及软件细节
    • 没有提及对结果不重要的价值观;它们只是默认值。请注意,如果存在对结果重要的任何其他值,也应提及这些值,以便读者能够获得验证结果正确性所需的所有信息,而无需阅读步骤定义。例如,如果特斯拉也有尾翼,且尾翼尺寸影响最大速度,则定义汽车的步骤也应提及“大尾翼”或其他内容
    我不确定你是否需要比我展示的更灵活的汽车定义步骤。我通常发现在大多数情况下只需要几个简单的步骤。开始时尽量保持简单,只有在需要的时候才构建更复杂的步骤


    另外,不要急于为所有数据组合编写场景(或场景大纲)。验收测试很慢,而且需要维护,所以您希望在向涉众公开所有重要需求的同时,尽可能少地进行验收测试。当你开始编写组合Cucumber场景时,想想你是否可以改为编写一个Cucumber场景作为示例,并在单元测试中测试所有的组合。

    这是一个非常好的问题,Dave Schweisguth给出了一个很好的答案,我也会补充

    当你有一个像你的汽车一样的结构和所有的配置选项,并且你想编写集成测试来处理不同种类的汽车时,你可以通过命名汽车来消除在你的功能中指定每一个保养细节的需要。例如,我可能有:

    • 拉力赛车:4轮驱动,6档,超轻底盘, 滚动条
    • 出租车:2轮驱动,4档,内部防污
    • 中年危机车:四轮驱动,双门轿车,敞篷车,真皮内饰
    然后您将编写如下功能:

    Given I have a rally car
    ...
    
    Given I have a taxi
    
    等等等等

    现在重要的是,在你身上,无论何时何地,你都不要回到细节

    Given I have a taxi
    Then I should have 2 wheel drive
    And I should have 4 gears
    
    这是不好的,因为您混合了两个抽象级别,详细级别和更高级别。相反,你应该为出租车司机编写出租车场景

    e、 g

    这意味着你的名字需要对你的利益相关者很重要

    这种方法的一个好处是,当您更改规范时,可以降低更改成本。例如,如果我们决定出租车应该是四轮驱动的,我们不必改变每一个场景,我们只需改变步骤def‘给定我有一辆出租车’

    我将按如下方式实施步骤defs

    Given 'I have a taxi' do
      create_taxi
    end
    
    module TaxiStepHelper
      def create_taxi
        create_car(
          engine: 
          drive: 
          ...
         )
       end
    
    我认为这种方法是“使用更高层次的抽象
    Given I have a taxi
    Then I should have 2 wheel drive
    And I should have 4 gears
    
    Given I have a taxi
    When my passengers puke over my interior
    Then it should be easy to clean
    
    Given 'I have a taxi' do
      create_taxi
    end
    
    module TaxiStepHelper
      def create_taxi
        create_car(
          engine: 
          drive: 
          ...
         )
       end