使用Docker和Golang进行便捷的MongoDB测试

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介: 本文讲的是使用Docker和Golang进行便捷的MongoDB测试,【编者的话】Docker的使用场景之一就是测试,在测试中,我们有时候会由于超时或者仅仅因为两个开发版本使用相同的数据库在同时运行而导致测试出错。
本文讲的是使用Docker和Golang进行便捷的MongoDB测试 【编者的话】Docker的使用场景之一就是测试,在测试中,我们有时候会由于超时或者仅仅因为两个开发版本使用相同的数据库在同时运行而导致测试出错。本文以Golang和MongoDB为例,介绍了如何使用Docker来简化和改进单元测试。

背景
我们正在不断寻找新技术来解决开发中遇到的问题。我们一直在使用Java+Spring,然而Java 8和Spring Boot为我们带来了新的生机,并改变了单一的Java应用为微服务模式(译者注:monolithic Java applications)。而当你有API的时候,你只需一个合适的前端框架就可以替代jsp和jQuery:在我们的案例中我们选择AngularJS。两年前我们第一次使用了Angular,现在所有的项目都引入了AngularJS。

超过10年的Java 在你的灵魂深处留下了深刻的印记
这两三年来,我一直在寻找更好的东西。在这个行业中,最好的事情是你会有各种选择。我们曾经使用NodeJS构建了几个项目,并学习了Ruby的服务配置管理框架Chef。当然我们也有一些Scala项目,并了解过Clojure、Haskell和Rust语言,后来我们发现了 Go 。虽然我们只使用Go语言编写了几个小服务,但是却对与Go相关的语言、标准库、工具和社区而震惊。有大量的博客文章解释了为什么不同的公司选择了Go,本文不再赘述。同时如果你想学习如何编写Go,可以查阅 A tour of Go ,如果你喜欢阅读请查看 Effective Go 或观看 A tour of Go 视频。

负载测试
可能我需要相当长的篇幅来介绍负载测试,所有的编程语言都需要编写单元测试代码,另外还有一些需要使用TDD方法和达到100%测试覆盖率的目标的方法。动态语言需要安排更多类型的测试,可能当你经过了上百次的测试,你的应用才能达到一个稳定的状态。痛苦的是,由于有不同的开发语言,所以你的测试需要很多的准备工作:曾经几秒钟就可以完成的事情,那现在可能会需要几分钟,甚至是几十分钟才能完成。因此,你要开始仓库(数据库)的调用,并建立集成测试的数据库开发的预载和清除方法。有时候集成测试可能会失败,而这可能是由于超时或者仅仅因为两个开发版本使用相同的数据库在同时运行。

使用Golang和Docker进行的测试
Golang不会有类似的问题,有了Golang的快速构建、测试周期和一些Docker魔法的支持,你能够在几秒内启动MongoDB Docker容器并运行所有的测试。这个真的是从开始到结束只需要几秒的时间,但是第一次运行除外,因为第一次运行的时候需要下载和提供MongoDB Docker容器。

我从这里得到真正的灵感,即使一直在寻找借口来确认这是否是正确的:

3AF91CF4-74A0-4577-98C9-ECE3FFE7C014.jpg


让我们做一些可以进行Docker实验的nice的事情
我已经研究Golang+AngularJS一段时间了,而且现在是最佳时间来证明Docker是否如宣传的一样神奇。对于OS X用户来说,涉及到Docker时会有个小烦恼:它只在Linux上面运行。是的,你可以运用Boot2Docker来安装到OS X上,而Boot2Docker将在虚拟化的Linux上运行Docker。我已经通过Ubuntu来使用Vagrant作为开发环境,因此我刚刚在这上面安装了Docker。

首先,我要熟悉Camlistore的实施环境并且复制它。特别感谢 Brad Fitzpartick ,你通过Camlistore和Golang标准程序库来完成了出色的工作。 Thanks!

可以通过 story_test.go 来找到实际测试。对于那些看不懂Golang的用户,我已经在最重要的代码部分添加了额外的注释。
Setup test environment
func TestStoryCreateAndGet(t *testing.T) {

// Start MongoDB Docker container
//
// One of the most powerful features in Golang
// is the ability to return multiple values from functions.
// In this we get:
// - containerID (type=ContainerID struct)
// - ip (type=string)
containerID, ip := dockertest.SetupMongoContainer(t)

// defer schedules KillRemove(t) function call to run immediatelly
// when TestStoryCreateAndGet(t) function is done,
// so you can place resource clenup code close to resource allocation
defer containerID.KillRemove(t)

app := AppContext{}

// Connect to Dockerized MongoDB
mongoSession, err := mgo.Dial(ip)

// Golang favors visible first hand error handling.
// Main idea is that Errors are not exceptional so you should handle them
if err != nil {
Error.Printf("MongoDB connection failed, with address '%s'.", Configuration.MongoUrl)
}

// close MongoDB connections when we're finished
defer mongoSession.Close()

app.mongoSession = mongoSession

// create test http server with applications route configuration
ts := httptest.NewServer(app.createRoutes())
defer ts.Close()

storyId := testCreate(ts, t) // run create test
testGet(ts, storyId, t) // run get test for created story
}

Post json document to http handler
func testCreate(ts *httptest.Server, t *testing.T) string {

postData := strings.NewReader("{\"text\":\"tekstiä\",\"subjectId\":\"k2j34\",\"subjectUrl\":\"www.fi/k2j34\"}")

// create http POST with postData JSON
res, err := http.Post(ts.URL+"/story", applicationJSON, postData)

// read http response body data
data, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
t.Error(err)
}

id := string(data)

// verify that we got correct http status code
if res.StatusCode != http.StatusCreated {
t.Fatalf("Non-expected status code: %v\n\tbody: %v, data:%s\n", http.StatusCreated, res.StatusCode, id)
}

// verify that we got valid lenght response data
if res.ContentLength != 5 {
t.Fatalf("Non-expected content length: %v != %v\n", res.ContentLength, 5)
}
return id
}

Test that previously created story exists
func testGet(ts *httptest.Server, storyId string, t *testing.T) {

// create http GET request with correct path
res, err := http.Get(ts.URL + "/story/" + storyId)
data, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
t.Error(err)
}

body := string(data)

// validate status code
if res.StatusCode != http.StatusOK {
t.Fatalf("Non-expected status code: %v\n\tbody: %v, data:%s\n", http.StatusCreated, res.StatusCode, body)
}

// validate that response has correct storyId
if !strings.Contains(body, "{\"storyId\":\""+storyId+"\",") {
t.Fatalf("Non-expected body content: %v", body)
}

// validate that content leght is what is should be
if res.ContentLength < 163 && res.ContentLength > 165 {
t.Fatalf("Non-expected content length: %v < %v, content:\n%v\n", res.ContentLength, 160, body)
}

}


眼见为实
因此,启动MongoDB Docker容器,将它配置到应用程序,然后用内置的测试直至创建HTTP服务器。然后,我们设置同样的路由给服务器,并对测试服务器运行两个请求,第一个来创建故事评论,另外一个来获取它。所有的数据都被存储了,并且从MongoDB中获取。那么所有这一切需要多久时间呢?

docker-testing-0d333fd6d1b21887e978d4d3110dc715.png

仅两秒以下!

docker-testing-with-race-detection-567c060af6235504c42111c3c5d33446.png

即使你运行一些条件选择器它仍只需要不到3秒 \o/

Docker是针对所有的用户,而不仅仅是Golang用户

对于那些可以使用Golang的用户,Docker也可以帮助你。它当然没有Golang那么快速,但是和使用外部的MongoDB服务器一样的快,而且没有额外的清理麻烦。毫无疑问,Docker是虚拟化业务中的游戏变化者,并且这些炒作也得到了很好的回报。这样就没有借口来针对MongoDB功能编写任何模拟测试。

原文链接:Painless MongoDB testing with Docker and Golang(翻译:吴锦晟 校对:李颖杰)

===============================================
译者介绍
吴锦晟 ,大连理工大学硕士研究生,就职于上海金桥信息股份有限公司技术中心。目前负责云计算、虚拟化、大数据及其信息可视化等方向的研究和应用。希望通过翻译技术文章于Dockone社区为Docker的步道做出微薄贡献。

原文发布时间为:2015-01-14
本文作者:吴锦晟 
本文来自云栖社区合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:使用Docker和Golang进行便捷的MongoDB测试
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
3月前
|
Ubuntu Cloud Native 测试技术
百度搜索:蓝易云【云原生之使用Docker部署ubuntu测试环境】
请注意,以上步骤仅是简单的使用Docker部署Ubuntu测试环境的示例。在实际应用中,您可能需要根据测试需求和应用场景进行更多的配置和优化。同时,在退出容器时,容器并未删除,您可以使用 `docker rm <容器名称>`命令来删除容器。在进行测试时,请谨慎操作,并确保对Docker的使用有一定的了解,以避免不必要的问题。
40 2
|
4月前
|
NoSQL MongoDB 数据安全/隐私保护
|
4月前
|
测试技术 Docker 容器
使用Docker构建多环境应用:开发、测试、生产环境
Docker已经成为了现代应用程序开发和部署的核心工具之一。通过使用Docker,开发团队可以轻松地在不同的环境中构建、测试和部署应用程序,从而提高开发速度和应用程序的可移植性。本文将介绍如何使用Docker构建多环境应用,包括开发、测试和生产环境,并提供丰富的示例代码,以帮助大家轻松应对不同环境的挑战。
|
14天前
|
jenkins 测试技术 持续交付
软件测试|docker搭建Jenkins+Python+allure自动化测试环境
通过以上步骤,你可以在Docker中搭建起Jenkins自动化测试环境,实现Python测试的自动化执行和Allure报告生成。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
34 6
|
1月前
|
NoSQL MongoDB Docker
docker安装MongoDB
docker安装MongoDB
21 0
|
1月前
|
SQL Apache 流计算
Apache Flink官方网站提供了关于如何使用Docker进行Flink CDC测试的文档
【2月更文挑战第25天】Apache Flink官方网站提供了关于如何使用Docker进行Flink CDC测试的文档
141 3
|
3月前
|
Web App开发 Linux 数据安全/隐私保护
Docker本地部署开源浏览器Firefox并远程访问进行测试
Docker本地部署开源浏览器Firefox并远程访问进行测试
139 1
|
4月前
|
Linux 数据库 数据安全/隐私保护
猿创征文|Linux centos7下利用docker快速部署SQLserver测试学习环境
猿创征文|Linux centos7下利用docker快速部署SQLserver测试学习环境
80 0
|
4月前
|
NoSQL MongoDB Docker
百度搜索:蓝易云【Scrapy框架之Docker安装MongoDB教程。】
现在,你已经成功在Scrapy框架中使用Docker安装并配置了MongoDB。你可以在Scrapy爬虫中使用MongoDB进行数据存储和处理。
218 0
|
4月前
|
监控 测试技术 时序数据库
软件测试/测试开发|Docker+Jmeter+InfluxDB+Grafana 搭建性能监控平台
软件测试/测试开发|Docker+Jmeter+InfluxDB+Grafana 搭建性能监控平台
51 0