在多个 Cucumber 场景大纲中使用相同的示例

Use the same examples in multiple Cucumber scenario outlines

如何为以下程序构建测试:

我正在为模拟组合电路编写单元测试框架。该框架将支持多个数字逻辑模拟器(JLS、Logisim、TKGate 等)因此,每个支持的模拟器的每个测试应该 运行 一次。

我的第一个想法是做这样的事情:

Scenario Outline:  Test of valid circuit
  when I run DLUnit with "testCircuit1.<type> testFile"
  Then I should see "All tests (4) passed." on stdout
  Examples:
      | type |
      | jls  |  # extension for JLS files
      | circ |  # extension for Logisim files
      | v    |  # extension for tkgate files

Scenario Outline:  Test of invalid circuit
  when I run DLUnit with "brokenCircuit1.<type> testFile"
  Then I should see "There were failures" on stdout
  Examples:
      | type |
      | jls  |
      | circ |
      | v    |

 # Many more tests to follow

虽然这在技术上可行,但它会导致功能代码可能难以维护:每个功能后面都有一个支持的模拟器列表。添加对附加模拟器的支持需要向每个测试添加相同的行。

我也可以创建jls.feature,然后使用sed自动创建logisim.featuretkgate.feature;但是,如果 Cucumber 提供更简单的内置解决方案,我想避免这种复杂性。

对您已有的东西没有太大的升级,但如何合并到一个场景大纲中呢? 添加新模拟器您将需要在一个示例中进行两项更改 table。您还可以根据两个模拟器或不同结果消息的不同有效测试文件的更改,使其更具可配置性。但是对于您现有的解决方案也可以这样做,因为您必须更改步骤和示例。

Scenario Outline:  Testing circuit
  when I run <kind> DLUnit with "<circuit>.<type> testFile"
  Then I should see <result> on stdout

      Examples: 
      | type | kind    | circuit         | result               |
      | jls  | valid   | testCircuit1    | All tests (4) passed |
      | jls  | invalid | brokenCircuit1  | There were failures  |
      | circ | valid   | testCircuit1    | All tests (4) passed |
      | circ | invalid | brokenCircuit1  | There were failures  |
      | v    | valid   | testCircuit1    | All tests (4) passed |
      | v    | invalid | brokenCircuit1  | There were failures  |

也许你可以在 RSpec 中做这样的事情:

describe DLUnit do
  [
    'jls', 'testCircuit1', true,
    'jls', 'brokenCircuit1', false,
    # ...
  ].each do |simulator, circuit, expected_validity|
    it "with the #{simulator} simulator finds the #{circuit} circuit #{expected_validity ? 'valid' : 'invalid' }" do
      actual_output = DLUnit.run "#{circuit.simulator}" # obviously I'm making this part up
      expect(actual_output).to include(expected_validity ? 'passed' : 'failures')
    end
  end
end

测试代码本身有点复杂,不过只需要写一次,RSpec输出应该就清楚了。