我需要搭建一个C++项目的持续集成的环境 (windows的程序),所以这几天学习了一下CruiseControl.Net
(以下简称CCNet),把整个过程跟大家分享一下。
如果你没有用过CCNet,跟着我实战一把,相信会领你入门的。
本文准备分三篇:
一、工具和环境的简要介绍
二、CCNet的配置(.Net项目)
三、CCNet中C++项目的配置
废话不多说了,实战开始!
工具准备:
首先说说我的实战环境
操作系统:Windows XP 专业版 其中 IIS 5.1
开发工具:Visual Studio.net 2003 Visual Studio 2005(说明一下,我的C++项目是03环境下的,05不是必需的,但是本文中我建立的C#项目是vs05的,03的效果应该是一样的,大家应该明白,实际上的问题在于.net
framework的版本,因为本文中用到的开源项目有些是基于.net framework2.0的,1.1版本的我没有实际用过,不敢乱说)
dotNet Framework版本: 装vs2005自带的2.0的。
Visual SourceSafe 2005 :英文版的,源代码版本管理工具,这个vss也自带.net
framework 2.0,我没有用过其他版本的vss,但是我认为对实战不会有影响。
需要的开源项目:
Cruise Control.Net 1.3
CruiseControl.NET-CCTray 1.3
NUnit-2.4.1-net-2.0
我在E盘建立了一个咱们试验的目录起个名字NetCruise。
安装Cruise Control.Net 1.3 到E:\NetCruise\CruiseControl.NET
安装 CruiseControl.NET-CCTray 1.3到E:\NetCruise\CCTray
安装 NUnit-2.4.1-net-2.0 到默认的位置了
目前的目录结构是这样的:
E:\NetCruise
CCTray
CruiseControl.NET
然后使用VSS建立一个源代码的数据库,步骤如下:
File - > New Database
在F:\MyVSS目录下建立(这个位置无所谓,只要你能记住就行),如下图:
一直下一步到结束。
第二部分
如果你对NUnit比较熟悉,可以直接进入第三部分
下面我们将建立一个简单的C# Library项目,并添加NUnit的测试。
加入代码
using System;
using System.Collections.Generic;
using System.Text;
namespace SimpleLib
...{
public class Calculater
...{
public static int add(int x, int y)
...{
return x + y;
}
public static int mul(int x, int y)
...{
return x * y;
}
}
}
然后为该项目添加测试,步骤如下:
添加测试类,先新建一个类,代码如下:
using System;
using System.Collections.Generic;
using System.Text;
namespace SimpleLib
...{
using NUnit.Framework;
[TestFixture]
public class CalculaterTest
...{
private Calculater calculater;
[SetUp]
protected void SetUp()
...{
calculater = new Calculater();
}
[Test]
public void TestAdd()
...{
int i5 = 5;
Assert.AreEqual(i5, Calculater.add(1, 4));
Assert.AreEqual(i5, Calculater.add(2, 3));
}
[Test]
public void TestMul()
...{
int i15 = 15;
Assert.AreEqual(i15, Calculater.mul(3, 5));
Assert.AreEqual(i15, Calculater.mul(5, 3));
}
[Test]
public void TestAddFailed()
...{
Assert.AreEqual(7, Calculater.mul(3, 2));
}
[Test]
public void TestAddAndMul()
...{
int i15 = 15;
Assert.AreEqual(i15, Calculater.mul(Calculater.add(2, 3), 3));
}
}其中TestAddFailed方法是故意让他测试失败的。
编译后,可以用NUnit查看一下结果,方法是启动NUnit,然后File->Open
Project然后选择编译生成的SimpleLib.dll文件,选择Run就可以看到结果了。
这里说一下NUnit的颜色,红色表示失败,绿色表示通过,黄色表示测试为运行。
下面就把该项目传到vss上去,这个我现在的机器上装的是vs05英文版的,只能用英文说明如何选择了。
File->Source Control->Add solution to Source
Control..
按默认的名称确定就可以了,如下图:
VSS的使用省略了不少,你应该为自己建立一个User,设置一个密码,每一个User就相当一个程序员嘛~
将除了VSS的所有东西都关掉吧!
在E:\NetCruise下新建一个project文件夹
哦了,所有的东西准备差不多了,下一篇就介绍CCNet的配置。
上一篇介绍完咱们的实战环境,下面主要介绍如何配置CCNet好让整个持续集成框架转起来。
这个配置文件是偶读了半天CCNet文档弄出来的,其实介绍CCNet如何配置的中文文章也不少,我阅读的时候感觉不太明白其中的每种路径干什么用的,所以我就着重讲一讲这些。
配置清单如下:
<cruisecontrol>
<!-- This is your CruiseControl.NET Server Configuration file. Add your projects below! -->
<project name="SimpleLib" >
<workingDirectory>E:\NetCruise\project</workingDirectory>
<artifactDirectory>E:NetCruise\artifactDirectory</artifactDirectory>
<category>Library Category</category>
<webURL>http://localhost/ccnet/server/local/project/SimpleLib/ViewProjectReport.aspx</webURL>
<modificationDelaySeconds>2</modificationDelaySeconds>
<triggers>
<intervalTrigger seconds="60"/>
</triggers>
<!--state type="yourStateManagerType" ..=""/-->
<sourcecontrol type="vss" autoGetSource="true" applyLabel="true">
<executable>C:Program Files\Microsoft Visual SourceSafe\ss.exe</executable>
<project>$/SimpleLib.root</project>
<username>ccnet</username>
<password>123456</password>
<ssdir>F:\MyVSS</ssdir>
<workingDirectory>E:\NetCruise\project</workingDirectory>
</sourcecontrol>
<!--labeller type="dateLabeller"/-->
<!--prebuild>
<yourFirstPrebuildTask ..=""/>
<yourOtherPrebuildTask ..=""/>
</prebuild-->
<tasks>
<devenv>
<solutionfile>E:NetCruise\project\SimpleLib\SimpleLib.sln</solutionfile>
<configuration>Debug</configuration>
<buildtype>Build</buildtype>
<executable>C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com</executable>
</devenv>
<nunit path="C:\Program Files\NUnit 2.4\bin\nunit-console.exe">
<assemblies>
<assembly>E:\NetCruise\project\SimpleLib\SimpleLib\bin\Debug\SimpleLib.dll</assembly>
</assemblies>
</nunit>
</tasks>
<publishers>
<xmllogger />
</publishers>
<externalLinks>
<externalLink name="google" url="http://somewhere/" />
<externalLink name="My Other Link" url="http://somewhere.else/" />
</externalLinks>
</project>
</cruisecontrol>
所有配置的路径可以参考第一篇文章来明确其含义。
project name随便填写,还是以你的项目名为准比较好。
<workingDirectory>E:\NetCruise\project</workingDirectory>
这个指定了工作目录,那么什么是工作目录,为什么要指定呢?
一般来说有两种目的:
首先是很多其他的配置项,尤其是那种需要填写路径的,当我们用相对路径的时候,就是以工作目录作为标准的。
其次是运行程序的目录,这个有什么用呢?举个例子,比如我用C++写了段程序,程序中用如下方法写了个文件:
fstream fs("Hello.txt");//之后省略
那么,此文件的最后输出的路径就是在运行程序的目录,你可以为该exe建立一个快捷方式,然后运行一下,就会发现此文件输出到该快捷方式所在的目录下了。
<artifactDirectory>E:\NetCruise\artifactDirectory</artifactDirectory>
这个路径输出CCNet的build日志,所以你也可以指定其他路径,虽说是日志,咱们可以打开看一下这些xml的内容,最终CCNet发布build结果的网站中的数据就是根据这些xml文件配合xsl生成的。
<category>Library Category</category>
这个元素可有可无,内容也随便起,看文档说是为了grouping projects,可以在CCTray中或者Dashboard(CCNet发布结果的网站)中显示,实际上我用没看出来什么……
<webURL>http://localhost/ccnet/server/local/project/SimpleLib/ViewProjectReport.aspx</webURL>
这个URL给CCTray和email用的,你添上你项目在Dashboard中的路径就可以了,刚开始不知道没关系,可以先不用这个元素,之后访问http://localhost/ccnet
去找到连接在加上就ok。
<modificationDelaySeconds>2</modificationDelaySeconds>
这个时间是控制代码last check in和开始build的时间,文档上举了个例子,比如说这个值设为10,代码7秒前check进来的,就sleep3秒后再build。文档上还说了,这个元素不用也可以,这是因为某些CVS不支持什么什么什么而存在的,默认值为0。(VSS做代码管理就可以不用设置这个,当然设置了也没什么毛病)
<triggers>
<intervalTrigger seconds="60"/>
</triggers>
这个元素是触发器,这里简单设置了一个,60秒检测一下版本服务器,看看有没有变化,如果没有更新的版本,那么就等待60后再检查,如果有最新版本那么就build了。如果你想实现每日构件,或者设置一些特殊的东西,比如周六周日不进行build,可以参考一下CCNet的文档,有关triggers的部分,还是很好理解的,还有例子。
<sourcecontrol type="vss"
autoGetSource="true" applyLabel="true">
<executable>C:\Program
Files\Microsoft Visual SourceSafe\ss.exe</executable>
<project>$/SimpleLib.root</project>
<username>ccnet</username>
<password>123456</password>
<ssdir>F:\MyVSS</ssdir>
<workingDirectory>E:\NetCruise\project</workingDirectory>
</sourcecontrol>
这个东西我相信大家能理解,就是配置源代码管理的部分,里面的路径参考第一篇环境介绍很容易理解。
其中有一点需要说明,一定要把这个workingDirectory和上面的工作目录设置为相同的,这个工作目录是CCNet从版本控制中获取项目放到的目的地,而上面的工作目录是build的目录,假如放到不同的目录中,那么你可以想象,每次都build同一个版本,而你最新的版本只不过每次都get到一个目录下,并不做任何事情。
<tasks>
<devenv>
<solutionfile>E:\NetCruise\project\SimpleLib\SimpleLib.sln</solutionfile>
<configuration>Debug</configuration>
<buildtype>Build</buildtype>
<executable>C:\Program
Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com</executable>
</devenv>
<nunit path="C:\Program
Files\NUnit 2.4\bin\nunit-console.exe">
<assemblies>
<assembly>E:\NetCruise\project\SimpleLib\SimpleLib\bin\Debug\SimpleLib.dll</assembly>
</assemblies>
</nunit>
</tasks>
这一块分两个部分:编译项目,运行自动化测试。
编译项目我采用了一个比较简单的方式,没用Nant什么的,devenv是VS自带的一个工具,咱们所有的IDE环境就是调用它来编译程序的。(当然你要是有vs2005的话也可以用msbuild来编译,我采用这个的目的是为了编译vc程序,因为C++的项目通常比较复杂,我不太懂怎么用一些其他的工具来编译,我发现这个方法很不错,vs03
05都可以用,还不用写新的东西来编译项目)。
nunit元素一目了然了,我保持沉默。
<publishers>
<xmllogger />
</publishers>
<externalLinks>
<externalLink name="google"
url="http://somewhere/"
/>
<externalLink name="My
Other Link" url="http://somewhere.else/"
/>
</externalLinks>
publishers元素中间放着如何发布整个build信息的方法,CCNet中叫Task,CCNet比较好的方式就是每个程序员电脑上都运行CCTray,浏览结果的时候看Dashboard发布的build信息。
<xmllogger/>就是输出上面artifactDirectory元素所指定路径中的log信息。
externalLinks就无所谓了,可以随便写,登陆Dashboard就能看到这些链接。
好了,将这些内容放到cc.config中,保存。
然后运行CCNet(有两种方式,命令行,或者windows服务)。这里用命令行方式(桌面上的那个就行)。
E:\NetCruise\CruiseControl.NET\server\ccnet.log 存储着运行时候的日志信息,如果有错误的话可以打开这个日志看一看,按照错误提示修改一下。
如果你成功了,那么非常恭喜你,心情一定很不错。
启动CCTray吧,CCTray的使用方法我这里不说了,比较简单的,如果使用不明白的话可以查一下相关的blog,写得很详细,图文并茂。
访问http://localhost/ccnet
看看吧!
然后可以从VSS上Get这个项目到另一个目录下,然后可以改变一下代码,或者测试用例,让他们都通过,再Check
in回去(中文版的vs忘了check in怎么翻译的,好像挺离谱)。等一会,如果你的配置都正确的话他会提取最新的版本然后重新build,发布测试结果!
好了,多做做试验,祝你成功!
下一篇将着重介绍VC项目如何利用CCNet进行持续集成~
首先说这篇主要参考了
http://build.sharpdevelop.net/ccnet/doc/CCNET/Using%20CruiseControl.NET%20with%20CppUnit.html
C++项目单元测试采用CPPUnit,CPPUnit的使用这里不详细讲了,有很多很不错的资料了。
在cppunit中设置输出xml文件名为Result.xml
服务器配置xml如下:
<project
name="CppCal"
queuePriority="1"
>
<workingDirectory>E:\NetCruise\project</workingDirectory>
<artifactDirectory>E:\NetCruise\project\CppCal\buildinfo</artifactDirectory>
<category>Cpp
Category</category>
<webURL>http://localhost/ccnet/server/local/project/CppCal/ViewProjectReport.aspx</webURL>
<modificationDelaySeconds>2</modificationDelaySeconds>
<triggers>
<intervalTrigger
seconds="60"/>
</triggers>
<!--state
type="yourStateManagerType" ..=""/-->
<sourcecontrol
type="vss"
autoGetSource="true"
applyLabel="true">
<executable>C:\Program
Files\Microsoft Visual SourceSafe\ss.exe</executable>
<project>$/CppCal.root</project>
<username>ccnetcpp</username>
<password>123456</password>
<ssdir>F:\MyVSS</ssdir>
<workingDirectory>E:\NetCruise\project</workingDirectory>
</sourcecontrol>
<!--labeller
type="dateLabeller"/-->
<!--prebuild>
<yourFirstPrebuildTask ..=""/>
<yourOtherPrebuildTask ..=""/>
</prebuild-->
<tasks>
<devenv>
<solutionfile>E:\NetCruise\project\CppCal\CppCal.sln</solutionfile>
<configuration>Debug</configuration>
<buildtype>Build</buildtype>
<executable>C:\Program
Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.com</executable>
</devenv>
<nunit>
<path>E:\NetCruise\project\CppCal\outPut\ProjectTest.exe</path>
<assemblies>
<assembly>*noassembly*</assembly>
</assemblies>
<outputfile>empty.xml</outputfile>
</nunit>
</tasks>
<publishers>
<merge>
<files>
<file>Result.xml</file>
</files>
</merge>
<xmllogger
/>
</publishers>
<externalLinks>
<externalLink
name="google"
url="http://somewhere/"
/>
<externalLink
name="My
Other Link" url="http://somewhere.else/"
/>
</externalLinks>
</project>
需要修改一个xls文件
下载地址
http://build.sharpdevelop.net/ccnet/doc/786491/unittests.xsl
需要替换文件,注意:这个连接下载下来是unittests.xml文件,需要手动改后缀名为xsl,然后替换
在本文中的位置是
E:\NetCruise\CruiseControl.NET\webdashboard\xsl\unittests.xsl
的文件。
这个文件是老外写的,用来能在CruiseControl.Net中显示CppUnit测试的结果,本来以为很厉害,但是打开以后研究了一下,发现还是比较简单的,有兴趣可以打开自己看看(配合CCNet生成的log**.xml文件)。
另外说一下这个Task,测试项目会生成一个exe,我们CPPUnit要用控制台那种,而且最终要以
return result.wasSuccessful() ? 0 : 1;
这种方式return,如果test成功他会返回0,CCNet如果发现程序返回0,那么表示测试成功,咱们的CCTray就是绿色的,如果返回1则相反,这样VC项目就会很好的进行构建。
<nunit>
<path>E:\NetCruise\project\CppCal\outPut\ProjectTest.exe</path>
<assemblies>
<assembly>*noassembly*</assembly>
</assemblies>
<outputfile>empty.xml</outputfile>
</nunit>
|