【问题标题】:Ordering jbehave stories to run sequentially订购 jbehave 故事以按顺序运行
【发布时间】:2012-08-22 18:15:17
【问题描述】:

我正在尝试按顺序运行 jbehave 故事。

我的集成测试包结构如下所示

src/it/some/package/name/packageA/a.story
src/it/some/package/name/packageB/b.story
src/it/some/package/name/c.story

我希望故事按照 a.story、b.story、c.story 的顺序运行

我尝试在 jBehave 中使用GivenStories,但它们似乎不起作用(可能是我没有正确指定它们)。如果有人可以指出 GivenStories 文本的创建,并且还显示一些关于 jbehave 在运行集成测试时如何创建排序的见解,我将非常感激,因为我看到在我的机器和詹金斯上运行的故事似乎正在产生不同的执行顺序。

非常感谢您对此的任何帮助。谢谢!

【问题讨论】:

    标签: java integration-testing jbehave


    【解决方案1】:

    我猜这个回复可能有点晚了,但无论如何。我们也在尝试 JB,似乎仍然存在很多关于使这项工作的问题,尤其是对于任何现实世界。

    我们已经给出了在模块内工作的故事,但是如果您尝试跨模块调用(例如,您有一个依赖 jar,其中包含您想要调用的常见故事,那么这似乎根本不起作用) .

    但在同一个模块中,请确保将 GS 条目放置在故事中的正确位置,如下所示:

    Story: Running BBB
    
    GivenStories: com/xxx/test/stories/test_aaa_user.story
    
    Given a BBB string
    When I set BBB to activate
    Then the BBB string is set to activate
    

    这在 BBB 之前运行 AAA 故事。

    【讨论】:

      【解决方案2】:

      我实际上想出了一个解决这个问题的方法,我认为它比 GivenStories 方便得多

      首先我添加了一个像这样的 maven surefire 配置

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${surefire.version}</version>
        <configuration>
          <includes>
             <include>**/*TesterSequence.java</include>
          </includes>
        </configuration>
      </plugin>
      

      SampleTesterSequence 的结构如下所示

      import org.junit.AfterClass;
      import org.junit.BeforeClass;
      import org.junit.runner.RunWith;
      import org.junit.runners.Suite;
      
      
      
      @RunWith(Suite.class)
      @Suite.SuiteClasses({ A.class,B.class, 
              C.class })
      public class SampleTesterSequence {
          @BeforeClass
          public static void beforeStories() throws Exception {
             //TODO Implement before story steps
          }
      
          @AfterClass
          public static void afterStories() throws Exception {
            //TODO Implement after story steps
          }
      }
      

      正如您所看到的,该套件将按照我在套件中提到的顺序运行故事 a、b、c,当 Surefire 运行测试时,它会查找以 TesterSequence 结尾的模式并首先运行该类,然后从该类中,它会按照指定的顺序执行我们想要运行的故事。

      【讨论】:

        【解决方案3】:

        发生这种情况的原因是因为 JBehave 按照它在文件系统中找到它们的顺序运行测试。为避免这种情况,您可以扩展 JBehave 的 StoryFinder 类并覆盖 findClassNames() 以使用存储在某处的有序列表(属性文件、build.xml 等):

        @Override
        public List<String> findClassNames(String searchIn, List<String> includes, List<String> excludes) {
        
            String[] orderedTestListArray = retrtieveTestNamesFromBuildXml();
        
            List<String> scannedTestList = scan(searchIn, includes, excludes);
            System.out.println("Scanned Test List: " + scannedTestList);
        
            List<String> finalTestList = new ArrayList<String>();
            for(String x: orderedTestListArray) {
                for(String y: scannedTestList) {
                    if(y.contains(x))
                        finalTestList.add(y);
                }
            }
        
            System.out.println("Final Ordered Test List: " + finalTestList);
            return classNames(normalise(finalTestList));
        }
        

        在这种情况下,我通过解析我的 ant build.xml 文件来检索orderedTestListArray,该文件包含我想要运行的有序测试列表:

        private String[] retrtieveTestNamesFromBuildXml() {
            String[] orderedTestListArray = null;
            InputStream iStream = null;
            try {
                File file = new File("build.xml");
        
                if(file.exists()) {
                   iStream = new FileInputStream(file);
                   DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
                   DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
                   Document doc = docBuilder.parse(iStream);       
                   NodeList propertyNodes = doc.getElementsByTagName("property");
        
                   String orderedTestListString = null;
        
                   for (int i = 0; i < propertyNodes.getLength(); i++) {
                       Element elementNode = (Element) propertyNodes.item(i);
                       if(elementNode.getAttribute("name").equals("xed.tests.to.run")) {
                           orderedTestListString = elementNode.getAttribute("value");
                           break;
                       }      
                   }
        
                   orderedTestListArray = orderedTestListString.split(",");
                   for(int i = 0; i <= orderedTestListArray.length-1; i++) {
                       orderedTestListArray[i] = orderedTestListArray[i].trim();
                       orderedTestListArray[i] = orderedTestListArray[i].substring(3, orderedTestListArray[i].length());
                   }
                }  
             }
             catch (Exception e) {
                 System.out.println("Error parsing XML info from build.xml");
                 e.printStackTrace();
                 System.exit(1);
             }
            finally {
                try
                {
                    if(iStream != null)
                        iStream.close();
                }
                catch (IOException e)
                { 
                    System.out.println("Error closing InputStream for build.xml");
                    e.printStackTrace();
                }
            }
            return orderedTestListArray;
        }
        

        最后,确保在从 ant 或 maven 运行时指定这个新的 StoryFinder 类,如下所示:

        storyFinderClass=fullyQualifiedNameOfNewStoryFinderClass
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-09-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-02
          相关资源
          最近更新 更多