本文将创建一个简单的动态链接库,并编写一个控制台应用程序使用该动态链接库,该动态链接库为“JAVA调用动态链接库DLL之JNative学习”中使用的DLL,只是项目及文件名称不同。
创建动态链接库项目:
1、打开Microsoft Visual Studio 2010,选择文件->新建->项目。
2、在新建项目窗口中选择其他语言->Visual C++->Win32。
3、选择Win32 项目,设置名称:simpleDLL,设置解决方案名:simpleDLL。 4、单击确定,在出现的Win32 应用程序向导的概述对话框中点击下一步。
5、在应用程序设置中,选择应用程序类型下的DLL。
6、勾选附加选项下的空项目。 7、单击完成创建项目。 向动态链接库添加类: 1、添加新类头文件。右键单击simpleDLL项目,添加->新建项,选择头文件(.h),设置名称为simpleDLL,单击添加。
2、添加新类源文件。右键单击simpleDLL项目,添加->新建项,选择C++ 文件(.cpp),设置名称为simpleDLL,单击添加。
3、为新类添加内容。内容如下:
头文件simpleDLL.h:
[cpp]?
view plain
?copy
//------------------?SimpleDLL.h?----------------?? ?? #pragma?once;?? ?? //该宏完成在dll项目内部使用__declspec(dllexport)导出?? //在dll项目外部使用时,用__declspec(dllimport)导入?? //宏DLL_IMPLEMENT在SimpleDLL.cpp中定义?? #ifdef?DLL_IMPLEMENT?? #define?DLL_API?__declspec(dllexport)?? #else?? #define?DLL_API?__declspec(dllimport)?? #endif?? DLL_API?int?add(int?x,?int?y);?//简单方法?? DLL_API?const?wchar_t*?getPlayUrl(const?wchar_t*?mgrIp,?long?mgrPort,?long?materialId);?? DLL_API?const?char*?getUrl(const?char*?mgrIp,?long?mgrPort,?long?materialId);??
源文件simpleDLL.cpp:
[cpp]?
view plain
?copy
//------------------?SimpleDLL.cpp?----------------?? ?? //注意此处的宏定义需要写在#include?"SimpleDLL.h"之前?? //以完成在dll项目内部使用__declspec(dllexport)导出?? //在dll项目外部使用时,用__declspec(dllimport)导入?? #define?DLL_IMPLEMENT?? ?? #include?"SimpleDLL.h"?? #include
创建引用动态链接库的应用程序: 1、在解决方案上单击鼠标右键->添加->新建项目。
2、在添加新项目中选择其它语言->Visual C++->Win32。
3、选择Win32 控制台应用程序,设置名称:simpleDLLTest。 4、单击确定,在出现的Win32 应用程序向导的概述对话框中点击下一步。
5、在应用程序设置中,选择应用程序类型下的控制台应用程序。
6、单击完成创建项目。 在控制台应用程序中使用类库的功能: 1、为SimpleDLLTest.cpp添加内容。如下所示:
[cpp]?
view plain
?copy
//?SimpleDLLTest.cpp?:?定义控制台应用程序的入口点。?? ?? #include?"stdafx.h"?? #include?"../SimpleDLL/SimpleDLL.h"?//添加头文件引用?? #pragma?comment(lib,?"..\\..\\SimpleDLL\\Release\\SimpleDLL.lib")?//添加lib文件引用??? #include?
2、引用simpleDLL项目。右键单击
SimpleDLLTest
项目,选择项目依赖项。
3、依赖于窗口中勾选SimpleDLL,单击确定。
4、设置SimpleDLLTest项目为活动项目。右键单击SimpleDLLTest项目,选择设为启动项目。
6、生成解决方案。Debug运行结果如下:
注意:现在创建的DLL只能由c++调用,C语言等其它语言是调用不了的!
我们来用工具看一下,在解决方案上单击鼠标右键,在Windows资源管理器中打开文件夹
我编译的是Release版本,所以打开Release文件夹,找到SimpleDLL.dll文件,用Depends工具打开它
目前编译的版本对MSVCR100.DLL还有依赖,这样复制到其它没有安装VS2010的电脑上是用不了的;
在项目上单击鼠标右键,属性:
在左侧的配置属性中选择常规,在右侧找到MFC的使用,选择在静态库中使用MFC
这里是修改MFC的使用,还有另一种方法:vs2010发布时去除msvcp100.dll和msvcr100.dll图解说明
再看函数,带有一些特殊字符,这样c++之外其它语言是调用不了的;我们需要在头文件的函数声明中添加extern "C"标志,代码如下:
[cpp]?
view plain
?copy
//------------------?SimpleDLL.h?----------------?? ?? #pragma?once;?? ?? //该宏完成在dll项目内部使用__declspec(dllexport)导出?? //在dll项目外部使用时,用__declspec(dllimport)导入?? //宏DLL_IMPLEMENT在SimpleDLL.cpp中定义?? #ifdef?DLL_IMPLEMENT?? #define?DLL_API?__declspec(dllexport)?? #else?? #define?DLL_API?__declspec(dllimport)?? #endif?? extern?"C"?DLL_API?int?add(int?x,?int?y);?//简单方法?? extern?"C"?DLL_API?const?wchar_t*?getPlayUrl(const?wchar_t*?mgrIp,?long?mgrPort,?long?materialId);?? extern?"C"?DLL_API?const?char*?getUrl(const?char*?mgrIp,?long?mgrPort,?long?materialId);??
重新编译,再
用
Depends工具打开它,可以发现依赖项已经没有了,函数名称也正常了:
转载自http://www.genealogy-computer-tips.com/testcs_dn/article/details/27237509
摘要:本教程不会介绍单元测试的基本理论知识,也不会和大家讨论在实际项目中是否需要写单元测试代码的问题。但是如果你此时想使用VS中的单元测试的工具来测试某个方法是否正确,可你又从来没真正实践过,那么本教程将带你一步一步使用VS2010集成的Unit Test进行断言(Assert)式验证数据的正确性,及代码覆盖率的查看。
?
关键词:Unit Test、单元测试、代码覆盖率、Assert、Twifly
?
正文:
????在本入门教程中我们假设来测试一个简单的加法运算方法是否正确。该方法能够接受任意个参数,参数类型可以是整型、字符型、浮点型,对于其他复杂类型我们这里暂时忽略。既然作为入门教程,那么下面我们按照详细的步骤开始。
?
1、????先创建一个空白解决方案(文件—>新建—>项目—>已安装的模版—>其他项目类型—>Visual Studio解决方案-->空白解决方案)命名为TestUnit。
2、????在新创建的解决方案(TestUnit)鼠标右键,选择添加—>新建项目—>控制台应用程序。
如下图所示:
?
3、????在控制台应用程序中,我们添加一个Operation类。添加一个简单的Add方法,该方法能对一个dynamic类型的列表的各项求和,简单地,我们这里假设传入的类型只可能是int、double、string类型,所以不对其他类型做异常捕捉。代码如下:
????public?class?Operation
????{
????????public?static?dynamic?Add(List
????????{
????????????dynamic?sum = 0;
????????????foreach?(var?n?in?numbers)
????????????{
????????????????var?s = n;
????????????????if?(s?is?string)
????????????????{
????????????????????s = -Convert.ToDouble(n);????//我们这里故意在转换前加了一个取反运算
????????????????}
????????????????sum += s;
????????????}
????????????return?sum;
????????}
?
????}
?
4、????现在我们来对Add方法做下单元测试。将光标放在Add方法名上,然后右键选择“创建单元测试(C)…”,如下图所示:
5、这时会弹出“创建单元测试”窗口,如下图所示,一般情况下直接点击确定即可。
?
6、如果直接点击确定按钮,系统将按照默认的命名规则
(
直接加
Test
后缀
)
生成测试文件。当然你也可以点击上图中的“设置
…
”按钮,在弹出的“测试生成设置”中进行规则修改。如下图所示
:
?
7、因为这是我们第一次创建单元测试项目,所以在输出选项中,我们选择默认的“创建新的Visual C#?测试项目”。在单击“确定”按钮后,要求我们填写测试项目的名称,名称自己随便,这里我们就用默认的TestProject1。点击“创建”即可。如果我们以后还对另一个方法进行单元测试,我们就可以在输出项目中直接选择“TestProject1”了,而不比再创建新的测试项目。如下图所示:
?
?
8、????这时,在解决方案下面,系统自动为我们创建了TestProject1测试项目和Solution Items(解决方案项)文件夹。
9、双击
TestProject1
测试项目下的
OperationTest.cs
文件,我们看一下系统为我们自动生成的测试代码。会发现主要有一下几点:
???在代码文件顶部增加了一个:using Microsoft.VisualStudio.TestTools.UnitTesting;
???在生成的OperationTest类上标记了[TestClass()],即使用了TestClassAttribute
???对测试类的方法AddTest标记了[TestMethod()]
???在测试类OperationTest中,定义了一个类型为TestContext的变量testContextInstance
???附加测试特性
?
10、我们现在要做的就是要对AddTest方法编写测试代码,一般情况下只需要简单地将TODO部分填写完整,将默认的代码:
?改成如下测试代码进行第一组测试:
///?
????????///Add?的测试
????????///
????????[TestMethod()]
????????public?void?AddTest()
????????{
????????????List
????????????dynamic?expected = 15;
????????????dynamic?actual;
????????????actual =?Operation.Add(numbers);
????????????Assert.AreEqual(expected, actual);
?????}
?????这个方法就是对整型1、2、3、4、5累加进行测试,我们期望的结果是15。Assert类的AreEqual方法用于验证实际结果和期望值是否相等。Assert断言类包含很多方法用于比较,在测试方法中,可以调用任意数量的?Assert?类方法,如?Assert.AreEqual()。Assert?类有很多方法可供选择,其中许多方法具有若干重载。详情可以参考MSDN的Assert类。
默认生成的代码中Assert.Inconclusive?语句用于指示该测试尚未准备好,不能运行(不能确定结果是否正确),所以当我们写好测试代码后,Assert.Inconclusive语句就可以删除了。
?
11、运行单元测试。打开测试视图(测试-->窗口-->测试视图),测试视图中会以列表的方式显示测试方法。右键菜单选择“运行选定内容”即可执行对该方法的测试,如下图所示:
?
VS2010接到测试的指令后,在测试完成后会自动弹出“测试结果”窗口,结果显示通过,表示测试结果值和预期结果相同。
?
12、上面一组单元测试(整型)结果是通过,但是我们知道对字符串操作是故意留有错误,但是实际过程中,那段代码并没有执行。所以我们还要对字符格式的数字进行测试,当然还有浮点型、负数等等,这些可以都单独测试,也可以一起测试。把测试代码改成
:
????????///?
????????///Add?的测试
????????///
????????[TestMethod()]
????????public?void?AddTest()
????????{
????????????List
????????????dynamic?expected = 15;
????????????dynamic?actual;
????????????actual =?Operation.Add(numbers);
????????????Assert.AreEqual(expected, actual);
?
????????????List
????????????dynamic?expected2 = 10;
????????????dynamic?actual2;
????????????actual2 =?Operation.Add(numbers2);
????????????Assert.AreEqual(expected2, actual2);
?
????????????List
????????????dynamic?expected3 = 22;
????????????dynamic?actual3;
????????????actual3 =?Operation.Add(numbers3);
????????????Assert.AreEqual(expected3, actual3);
????????}
我们再进行一次测试(第二组测试)。每次测试代码修改后,会提示我们刷新更新,直接点击刷新按钮即可。
?
?看看测试结果如何:
?
?这个时候我们发现测试显示未通过,右键菜单单击“查看测试结果详细信息”,如下图所示:
?
??
13、错误消息提示期望指为10,但实际结果为-10,我们很容易知道是下面组数据出了问题:
List
找到代码:s = -Convert.ToDouble(n);????//我们这里故意在转换前加了一个取反运算,把前面的取反运算符去掉,改成:s =?Convert.ToDouble(n);????再进行一次测试,测试结果会按预期的方式显示为通过。
?
14、调试单元测试。上面能一下子就把错误修改,是因为错误是我们故意设置的。在实际开发中,找错误也许并不明显,通常是需要调试后才容易找到。调试单元测试和平时断点测试是一样的,在需要的地方设置断点后,在测试视图中右键选择“调试选定内容”,接下来就是大家所熟悉的断点调试步骤了。如下图所示:
??
15、查看代码覆盖率。单元测试的编写,涉及到很多要求,但是最基本的就是需要编写多组数据对各个分支代码都至少需要执行一遍。如我们前面第一组直接测试整型相加(1、2、3、4、5)测试结果15为通过,没找到潜在的错误,是因为有些代码没被执行。查看代码覆盖率就能帮助你检测测试数据是否会覆盖所有分支代码。
????如下图所示,右键选择“覆盖率结果”,可以查看代码覆盖率。
?
第一组数据测试代码覆盖率:
?
第二组数据测试代码覆盖率:
??
16、代码覆盖率默认演示显示说明:
?
颜色代码 说明 浅蓝色 指示在测试运行过程中执行了整个代码行。 浅褐色 指示在测试运行过程中仅执行了代码行的部分代码块。 红棕色 指示在测试运行过程中未执行此行。
当然这些默认颜色可以在工具菜单下的选项中进行设置,如下图所示:
?
17、如果在查看代码覆盖率中出现如下提示,则我们需要简单配置一下
?
在“测试视图”中,找到Solution Items(解决方案项)文件夹下的Local.testsettings,双击打开“测试设置”窗口,选择“数据和诊断”,将代码覆盖率设置为启用,然后点击“配置”对代码覆盖率进行配置,如下图所示:
?
在我们的控制台应用程序前打勾,然后点击确定按钮
?
最后对“测试设置”点击“应用”按钮完成代码覆盖率的配置。重新运行测试,就可以查看代码覆盖率了。
?
到这里已经完成了如何简单使用VS2010自带的单元测试工具进行断言式Assert条件测试,当然以后我们还可能接触到CollectionAssert类来比较集合对象、StringAssert?类来对字符串进行比较等等,在后面的教程中我们将接触到。
?
最后如果对本入门教程仍有疑问,可以参考MSND官方的教程文章。
?
MSDN官方参考:
?
演练:创建并运行单元测试
http://www.genealogy-computer-tips.com/zh-cn/library/ms182532.aspx
?
如何:创建和运行单元测试
http://www.genealogy-computer-tips.com/zh-cn/library/dd286656.aspx
?
单元测试分析
http://www.genealogy-computer-tips.com/zh-cn/library/ms182517.aspx
?
使用?Assert?类
http://www.genealogy-computer-tips.com/zh-cn/library/ms182530(v=vs.100).aspx
?
演练:运行测试并查看代码覆盖率
http://www.genealogy-computer-tips.com/zh-cn/library/ms182534.aspx
?
?
? ? ??
?从一个简单的实例入手
?一、编写需要测试的类,该类为String对象扩展了IsIn方法,目的是判断当前字符串是否存在于指定的数组中,代码如下:
View Code
public
static
class
HelperString {
public
static
bool
IsIn(
this
string
str,
string
[] strs) {
if
(strs
==
null
) {
if
(str
==
null
) {
return
true
; }
return
false
; }
foreach
(
string
item
in
strs) {
if
(str
==
item) {
return
true
; } }
return
false
; } }
?二、右键方法名称 --> 选择创建单元测试? --> 弹出创建单元测试对话框 -->? 点击确定(如果不使用默认设置可选择窗口左下角的“设置”按钮)?
?三、VS会自动创建Test项目,如果是默认设置,测试项目生成的类名称 = “HelperStringTest”,用于测试“IsIn”方法的名称为“IsInTest”。
?四、测试属性
????? 每个测试类都会标记[TestClass]属性,方法为[TestMethod]。
?五、在IsInTest方法中添加测试代码,以下我为IsIn方法写了6个测试用例。
????
View Code
Assert.AreEqual(
true
, HelperString.IsIn(
"
1
"
,
new
string
[] {
"
1
"
,
"
2
"
,
"
3
"
})); Assert.AreEqual(
false
, HelperString.IsIn(
"
5
"
,
new
string
[] {
"
1
"
,
"
2
"
,
"
3
"
})); Assert.AreEqual(
false
, HelperString.IsIn(
"
5
"
,
null
)); Assert.AreEqual(
true
, HelperString.IsIn(
null
,
null
)); Assert.IsTrue(HelperString.IsIn(
"
2
"
,
new
string
[] {
"
1
"
,
"
2
"
,
"
3
"
})); Assert.IsFalse(HelperString.IsIn(
"
4
"
,
new
string
[] {
"
1
"
,
"
2
"
,
"
3
"
}));
?六、Assert测试帮助类介绍
???? 详细请查阅 http://www.genealogy-computer-tips.com/zh-cn/library/microsoft.visualstudio.testtools.unittesting.assert.aspx
?七、右键点击测试方式 --> 选择运行测试? --> 在测试接口窗口中查看测试结果,运行测试的快捷键(Ctrl + R + T),如果需要进行调试则可以按F5。
?至此,一个简单的单元测试已经完工了,下面我们来查看代码覆盖率(即本次运行的单元测试覆盖了被测试程序集的哪部分代码块),设置方法如下:
?单击菜单栏中的测试 --> 编辑测试设置 --> 本地(local.testsettings) --> 弹出测试设置对话框 --> 在左边的列表中选择数据和诊断 --> 在右边名称列表框中选择代码覆盖率,选中
?-->? 单击名称列表框上边的配置按钮 --> 弹出代码覆盖率详细信息对话框 --> 选择要检测的项目(即“IsInfo”方法所在的程序集) --> 单击确定
?重新运行测试程序 --> 单击菜单栏中的测试 --> 窗口 --> 代码覆盖率 --> 在VS下方的代码覆盖率窗口中即可查看被设置程序集的代码覆盖率情况,也可以在被测试的类中查看代码覆盖
?情况(如果没有被覆盖,则以淡红色显示)。
?接下来我们创建一个简单的数据驱动的单元测试,提取出一个表中的记录,并保存在一个变量中,以备后用。
?一、在测试类中添加一个方法“FromSqlTest”,表示数据源来自SqlServer,并添加[TestMethod]属性(这是每个单元测试方法必须得属性)。
?二、为测试方法添加[DataSource]标签,全部代码如下所示:
View Code
[DataSource(
"
System.Data.SqlClient
"
,
@"
Data Source=HNJCHENNANFEI; Initial Catalog=Linq; Integrated Security=True
"
,
"
Linq_Class
"
, DataAccessMethod.Sequential), TestMethod]
public
void
ToSqlTest() {
string
str
=
TestContext.DataRow[
"
Name
"
].ToString(); }
?三、DataSource参数介绍
????? 1、获取此数据源的固定提供程序的名称。
????? 2、设置连接字符串
????? 3、设置数据表名
????? 3、枚举值,当前设置为按顺序读取数据表中的记录,另一个选项是随机
????? 详细请查阅 http://www.genealogy-computer-tips.com/zh-cn/library/microsoft.visualstudio.testtools.webtesting.datasource.aspx
? 四、TestContext
????? TestContext.DataRow会循环获得数据表中的每条记录
????? 详细请查阅 http://www.genealogy-computer-tips.com/zh-cn/library/microsoft.visualstudio.testtools.unittesting.testcontext_members(v=VS.80).aspx
?
转载于:https://www.genealogy-computer-tips.com/cnfblog/archive/2011/05/19/2051314.html
0条大神的评论