为Openshift + MongoDb应用程序编写验收测试
验收测试用于确定是否满足规范要求。 它应该在与生产环境尽可能相似的环境中运行。 因此,如果您的应用程序已部署到Openshift中,则您将需要一个与生产环境中使用的帐户平行的帐户,以运行测试。 在这篇文章中,我们将为部署到Openshift的应用程序编写验收测试,该应用程序使用MongoDb作为数据库后端。
部署的应用程序是一个非常非常简单的库,它返回所有可借出的书。 该应用程序使用MongoDb来存储与书籍有关的所有信息。
因此,让我们开始描述先前应用程序的目标,功能,用户故事和接受标准。
目标 :扩大对大多数人的授课范围。
功能 :显示可用的书。
用户故事 :浏览目录->为了查找我想借的书,作为用户,我希望能够浏览所有书。 验收标准 :应该查看所有可用的书。
场景:
鉴于我想借一本书
当我在目录页面时
然后,我应该会看到可用的书籍信息:罐子之王– 1299 – LOTRCoverUrl,霍比特人– 293 – HobbitCoverUrl
注意,这是一个非常简单的应用程序,因此接受标准也很简单。
对于此示例,我们需要两个测试框架,第一个用于编写和运行验收测试,另一个用于管理NoSQL后端。 在这篇文章中,我们将使用修昔底德的ATDD和NoSQLUnit对付MongoDB的 。
该应用程序已经部署在Openshift中 ,您可以查看https://books-lordofthejars.rhcloud.com/GetAllBooks
Thucydides是一种工具,旨在简化编写自动验收和回归测试的过程。
Thucydides使用WebDriver API访问HTML页面元素。 而且还可以帮助您通过使用具体的编程模型来组织测试和用户故事,创建已执行测试的报告,最后还可以测量功能覆盖率。
要用Thucydides编写验收测试,应遵循以下步骤。
- 首先,选择您的功能之一的用户故事。
- 然后实现PageObject类。 PageObject是一种将Web应用程序的用户界面元素建模为对象的模式,因此测试可以以编程方式与其交互。 请注意,在这种情况下,我们正在编码“如何”访问HTML页面。
- 下一步是实现步骤库。 此类将包含执行操作所需的所有步骤。 例如,创建新书需要打开addnewbook页面,插入新数据,然后单击提交按钮。 在这种情况下,我们正在编码“什么”来实现验收标准。
- 最后,按照定义的验收标准并使用先前的步骤类对选定的用户故事进行编码。
NoSQLUnit是一个JUnit扩展,旨在使我们能够管理所需的NoSQL引擎的生命周期,帮助我们将数据库维护为已知状态并简化为NoSQL应用程序编写测试的方式。
NoSQLUnit由两组JUnit规则和两个注释组成。 在当前情况下,我们不需要管理NoSQL引擎的生命周期,因为它是由外部实体( Openshift )管理的。
因此,让我们开始工作:
我们要做的第一件事是创建一个不包含测试代码的要素类。 它用作表示需求结构的一种方式。
public class Application {@Featurepublic class Books {public class ListAllBooks {}}}
请注意,每个实现的功能都应包含在带有@Feature注释的类中。 特色类的每种方法都代表一个用户故事。
下一步是创建PageObject类。 请记住,PageObject模式将Web应用程序的用户界面建模为对象。 因此,让我们看一下html文件,以检查必须映射的元素。
<table id='listBooks' cellspacing='0' cellpadding='5'><caption>List of Available Books<caption><tr><th>Title<th><th>Number Of Pages<th><th>Cover<th><tr>.....<table>
这里最重要的是表标记具有一个名为listBooks的ID ,将在PageObject类中使用该ID以获得对其参数和数据的引用。 让我们编写页面对象:
@DefaultUrl('http:books-lordofthejars.rhcloud.comGetAllBooks')public class FindAllBooksPage extends PageObject {@FindBy(id = 'listBooks')private WebElement tableBooks;public FindAllBooksPage(WebDriver driver) {super(driver);}public TableWebElement getBooksTable() {Map<String, List<String>> tableValues = new HashMap<String, List<String>>();tableValues.put('titles', titles());tableValues.put('numberOfPages', numberOfPages());tableValues.put('covers', coversUrl());return new TableWebElement(tableValues);}private List<String> titles() {List<WebElement> namesWebElement = tableBooks.findElements(By.className('title'));return with(namesWebElement).convert(toStringValue());}private List<String> numberOfPages() {List<WebElement> numberOfPagesWebElement = tableBooks.findElements(By.className('numberOfPages'));return with(numberOfPagesWebElement).convert(toStringValue());}private List<String> coversUrl() {List<WebElement> coverUrlWebElement = tableBooks.findElements(By.className('cover'));return with(coverUrlWebElement).convert(toImageUrl());}private Converter<WebElement, String> toImageUrl() {return new Converter<WebElement, String>() {@Overridepublic String convert(WebElement from) {WebElement imgTag = from.findElement(By.tagName('img'));return imgTag.getAttribute('src');}};}private Converter<WebElement, String> toStringValue() {return new Converter<WebElement, String>() {@Overridepublic String convert(WebElement from) {return from.getText();}};}}
使用@DefaultUrl我们设置要映射的URL,使用@FindBy我们映射ID为listBooks的Web元素,最后映射返回生成的html表内容的getBooksTable()方法。
接下来要做的是实现步骤类。 在这种简单的情况下,我们只需要两步,第一步打开GetAllBooks页面,另一步断言该表包含期望的元素。
public class EndUserSteps extends ScenarioSteps {public EndUserSteps(Pages pages) {super(pages);}private static final long serialVersionUID = 1L;@Steppublic void should_obtain_all_inserted_books() {TableWebElement booksTable = onFindAllBooksPage().getBooksTable();List<String> titles = booksTable.getColumn('titles');assertThat(titles, hasItems('The Lord Of The Rings', 'The Hobbit'));List<String> numberOfPages = booksTable.getColumn('numberOfPages');assertThat(numberOfPages, hasItems('1299', '293'));List<String> covers = booksTable.getColumn('covers');assertThat(covers, hasItems('http:upload.wikimedia.orgwikipediaen662Jrrt_lotr_cover_design.jpg', 'http:upload.wikimedia.orgwikipediaen44aTheHobbit_FirstEdition.jpg'));}@Steppublic void open_find_all_page() {onFindAllBooksPage().open();}private FindAllBooksPage onFindAllBooksPage() {return getPages().currentPageAt(FindAllBooksPage.class);}}
最后是验证验收标准的课程:
@Story(Application.Books.ListAllBooks.class)@RunWith(ThucydidesRunner.class)public class FindBooksStory {private final MongoDbConfiguration mongoDbConfiguration = mongoDb().host('127.0.0.1').databaseName('books').username(MongoDbConstants.USERNAME).password(MongoDbConstants.PASSWORD).build();@Rulepublic final MongoDbRule mongoDbRule = newMongoDbRule().configure(mongoDbConfiguration).build();@Managed(uniqueSession = true)public WebDriver webdriver;@ManagedPages(defaultUrl = 'http:books-lordofthejars.rhcloud.com')public Pages pages;@Stepspublic EndUserSteps endUserSteps;@Test@UsingDataSet(locations = 'books.json', loadStrategy = LoadStrategyEnum.CLEAN_INSERT)public void finding_all_books_should_return_all_available_books() {endUserSteps.open_find_all_page();endUserSteps.should_obtain_all_inserted_books();}}
在上一堂课中应该考虑一些事项:
- @Story应该收到一个使用@Feature批注定义的类,以便Thucydides可以正确创建报告。
- 我们使用MongoDbRule建立与远程MongoDb实例的连接。 请注意,由于端口转发具有Openshift功能,因此我们可以使用本地主机地址,因此尽管使用了本地主机,但实际上我们正在管理远程MongoDb实例。
- 使用@Steps Thucydides将创建先前步骤库的实例。
- 最后使用@UsingDataSet批注在运行测试之前将数据填充到MongoDb数据库中。
{'book':[{'title': 'The Lord Of The Rings','numberOfPages': '1299','cover': 'http:upload.wikimedia.orgwikipediaen662Jrrt_lotr_cover_design.jpg' }, {'title': 'The Hobbit','numberOfPages': '293','cover': 'http:upload.wikimedia.orgwikipediaen44aTheHobbit_FirstEdition.jpg'}]}
请注意, NoSQLUnit通过在每次测试执行之前清理数据库并将其定义为json文件中的已知数据来填充数据库, 从而将数据库保持为已知状态。
还请记住,此示例非常简单,因此仅显示了Thucydides和NoSQLUnit功能的一小部分。 继续观看两个网站: http : //thucydides.info和https://github.com/lordofthejars/nosql-unit
参考:来自我们的JCG合作伙伴 Alex Soto的Openshift + MongoDb应用程序的编写验收测试,位于One Jar To Rule All All博客上。
翻译自: https://www.javacodegeeks.com/2012/12/writing-acceptance-tests-for-openshift-mongodb-applications.html
为Openshift + MongoDb应用程序编写验收测试相关推荐
- openshift_为Openshift + MongoDb应用程序编写验收测试
openshift 验收测试用于确定是否满足规范要求. 它应在与生产环境尽可能相似的环境中运行. 因此,如果您的应用程序已部署到Openshift中,则您将需要一个与生产环境中使用的帐户平行的帐户,以 ...
- 使用NoSQLUnit测试Spring Data MongoDB应用程序
Spring Data MongoDB是Spring Data项目中的项目,它提供了Spring编程模型的扩展,用于编写使用MongoDB作为数据库的应用程序. 要使用NoSQLUnit为Spring ...
- 基于DCMTK的DICOM相关程序编写攻略
2008年09月10日 星期三 15:35 基于DCMTK的DICOM相关程序编写攻略 前言: 由于现在的医学影像设备的图像存储和传输正在逐渐向DICOM标准靠拢,在我们进行医学图像处理的过程中,经常 ...
- PLSQL程序编写杂烦数据表信息编写批量排版
--PLSQL程序编写杂烦数据表信息编写批量排版 SELECT 'cra.' || lower(t.column_name) ||','FROM dba_tab_columns tWHERE t.ta ...
- 计算机脚本程序编写,实验三-shell脚本程序设计.docx
实验报告 课程名称 Linux 系统实践 实验项目LINUX SHELL脚本程序设计 实验仪器PC 系别计算机学院 专业网络工程 班级 / 学号 网 1702/2017011463 学生姓名孟启贤 实 ...
- 分别统计出其中英文字母、空格、数字和其它字符的个数 matlab 程序,编写一段程序,要求先输入一行字符,然后分别统计出其中英文...
编写一个求和的程序,要求能任意输入两个整数,求和 用javascript写 +=functionadd(){varA=document.getElementById("a").va ...
- 程序编写经验教训_编写您永远都不会忘记的有效绩效评估的经验教训。
程序编写经验教训 This article is intended for two audiences: people who need to write self-evaluations, and ...
- java编写某计算器控制台程序_用java程序编写一个计算器
点击查看用java程序编写一个计算器具体信息 答:给你一个参考,希望不要被百度吞了当晚餐 import java.awt.BorderLayout; import java.awt.GridLayou ...
- 基于Asterisk的VoIP开发指南(2)——Asterisk AGI程序编写指南
5. Asterisk AGI程序编写指南 5.1概述 很多时候,我们需要在拨号方案中做某些业务逻辑的判断或者外部数据库的查询,根据具体地需要,有几种做法: 1.使用Asterisk的通道变量. ...
最新文章
- 红薯因 Swift 重写开源中国失败,貌似欲改用 Python
- java jni.h_java-如何使jni.h被找到?
- java 画图保存图片_将绘图保存到图像文件,而不是使用Matplotlib显示它
- boost::math模块计算艾里函数的零点的测试程序
- ubuntu crontab 不执行的解决方法
- Oracle HA 之 SERVICE和DRM实战
- iOS开发之UITableViewController指定刷新cell 或section
- rbf java_RBF网络
- ArcView GIS 应用与开发技术(9)- 创建空间数据
- 基于html的火柴人羽毛球网页游戏设计
- 高中数学排列组合公式/排列组合计算公式
- 电子设计教程39:软启动电路-观察浪涌电流
- pandas dataframe drop函数
- 基于STM32的12864液晶理解
- pve万兆网卡驱动_家庭万兆方案性价比之选,10G网速不是梦!战在当下,布局未来!...
- 小程序-视图与逻辑-页面导航
- day1-C++学习
- Armijo-Goldstein法则和Wolfe-power法则图解
- android java 指针异常处理,Android程序员日常开发中异常总结
- 开维控制精灵 Ctrl js 华为手机群发短信
热门文章
- Multi-catch parameters are not allowed for source level below 1.7 解决方法
- Request获取参数封装方式
- spring boot注释_Spring Boot中的@SpringBootConfiguration注释
- java 读取集合到流中_Java 10:将流收集到不可修改的集合中
- 使用Spring Security进行简单身份验证
- CUBA 7.2 –有什么新功能?
- javafx 自定义控件_JavaFX技巧10:自定义复合控件
- 红帽 jboss_红帽正式宣布发布JBoss BPM Suite 6和JBoss BRMS 6
- input发送a.jax_JAX-RS 2.0:自定义内容处理
- jooq权限配置_将jOOQ与Spring结合使用:配置