VS2015 c++程序单元测试初探——从0到1中所遇到的错误和历程 VS2015安装与C++进行简单单元测试 VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项 断言(ASSERT)的用法 Visaul Studio2015安装以及c++单元测试使用方法 带你玩转Visual Studio——单元测试 C++单元测试一:并非看上去那么简单——几个很实际的问题

实现过程

一开始对单元测试这个东西感觉很恐惧,在看过雪晴的博客后,觉得自己可以试试学学,找到了一篇博客,地址:

前面的建立和初始化都比较easy,但很快遇到了一个问题,例子中是对一个类的接口进行的测试,是否能对非类接口(如函数进行测试呢),问了雪晴后,发现应该是可以的,那么就自己试一下吧。

准备试试测试void word_to_word(word_count* word, wprd_count* word1);代码如下:

class word_count
{
    //单词计数器类
public:
    //friend struct std::hash<word_count>;
public:
    //string* temp;//用来存真实的单词
    string* str;//单词的名字    
    string* num;//数字后缀
    int num_rear;//数字后缀的开始位
    int str_count;//单词个数
    int flag;//判断是否在高频内
    int size;//单词
    string* word;//单词部分
    
    word_count* next_ptr;
    word_count();
    ~word_count();
};
void word_to_word(word_count* word, word_count* word1) {
    //把所有的word的值赋给word1
    *(word1->str) = *(word->str);
    
    *(word1->num) = *(word->num);
    
    word1->num_rear=word->num_rear;
    //数字后缀的开始位
    word1->str_count = word->str_count;
    //单词个数
    word1->flag = word->flag;
    word1->size = word->size;
    *(word1->word) = *(word->word);
    word1->next_ptr=word->next_ptr;

但是很快遇到了麻烦,这个函数是为了将对象word中的string和其他值(大多为int类型)都赋给word1类。(在这里仔细想了想发现之所以写这个函数完全是因为对OOP的理解不到家,明明就定义了一个对象,为什么还要做这种复杂的内存转储操作呢……直接定义一个新的不就好了,指针不就是干这个的吗……这就等于在读取单词的过程中我自己疯狂创建了无数个副本,而且他们全部能活到最后,为了验证我的猜测,等一下我要去试一下改改代码,看看是不是这样)。

好吧回到原题,这中间有这样的操作,但博客中只提到了int类型的比较,所以我现在还不确定该怎么使用assert,那么就来摸索一下。

之后我想,string类重载了操作符==,那会不会可以直接对内部的string进行Areequal操作呢,代码如下:

 VS2015 c++程序单元测试初探——从0到1中所遇到的错误和历程
VS2015安装与C++进行简单单元测试
VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项
断言(ASSERT)的用法
Visaul Studio2015安装以及c++单元测试使用方法
带你玩转Visual Studio——单元测试
C++单元测试一:并非看上去那么简单——几个很实际的问题

接下来是链接到obj文件上,链接完成,但是程序报错,错误如下:

Microsoft::VisualStudio::TestTools::UnitTesting::Assert::AreEqual”: 15 个重载中没有一个可以转换所有参数类型

查看到代码,发现是areEqual无法判别string类是否相等,继续查阅资料,发现StringAssert类,但是经过阅读发现,StringAssert类大多是对子串和包含/开头结尾来判断的,没有找到合适的方法,于是回头找AreEqual的重载类型,发现,合适的重载参数应该为:

 VS2015 c++程序单元测试初探——从0到1中所遇到的错误和历程
VS2015安装与C++进行简单单元测试
VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项
断言(ASSERT)的用法
Visaul Studio2015安装以及c++单元测试使用方法
带你玩转Visual Studio——单元测试
C++单元测试一:并非看上去那么简单——几个很实际的问题

VS2015 c++程序单元测试初探——从0到1中所遇到的错误和历程
VS2015安装与C++进行简单单元测试
VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项
断言(ASSERT)的用法
Visaul Studio2015安装以及c++单元测试使用方法
带你玩转Visual Studio——单元测试
C++单元测试一:并非看上去那么简单——几个很实际的问题

由于本例中都是大写字母,所以就用true即可

但是他继续报错,说明还不对,之后我又发现了string^类型的字串,据说是托管类型的,是什么意思呢 感觉要崩。关于这个托管类型的意义,我感觉有必要专门花时间去学习了了解了。。。不知道看到的老师和同学有没有能教教我的。

最后我放弃了采用Assert,决定#include <assert.h>,然后用assert(word1==word2)的方式来判断。

最终代码如下:

void TestMethod1()
        {
            word_count* h1=new word_count();
            word_count* h2=new word_count();
            h1->flag = 12;
            
            *(h1->str) = "strtest123";
            *(h1->num) = "123";
            *(h1->word) = "strtest";
            h1->num_rear = 7;
            h1->size = 10;
            h1->str_count = 1;
            h1->next_ptr = NULL;
            word_to_word(h1, h2);
            Assert::AreEqual(h2->flag,h1->flag);
            Assert::AreEqual(h2->num_rear, h1->num_rear);

            assert(*(h1->word)== *(h2->word));
            assert(*(h1->str)== *(h2->str));
            assert(*(h1->num)== *(h2->num));
            assert(*(h1->word) == *(h2->word));
            Assert::AreEqual(h2->str_count, h1->str_count);
            Assert::AreEqual(h2->size, h1->size);
            /*    Assert::AreEqual(*(h1->str), *(h2->str)); 
            Assert::AreEqual(*(h1->num), *(h2->num)); */
            //Assert::AreEqual(*(h1->word), *(h2->word));
            
            //        
            // TODO:  在此处添加测试逻辑
            //
        };

然后我开始进行链接,具体操作子啊教程中有。但是我没想到的是,由于我的工程是含有预编译头的,所以一开始我只link了../ConsoleApplication4/Debug/word_count.obj,不知道要链接../ ConsoleApplication4/Debug/stdafx.obj,因此一直报如下错误:

 VS2015 c++程序单元测试初探——从0到1中所遇到的错误和历程
VS2015安装与C++进行简单单元测试
VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项
断言(ASSERT)的用法
Visaul Studio2015安装以及c++单元测试使用方法
带你玩转Visual Studio——单元测试
C++单元测试一:并非看上去那么简单——几个很实际的问题

先预告一下,事实证明,接下来一个小时更加痛苦的经历都是由于我对warning没有重视,以为问题不大,所以一直崩盘。。。。

这里我们首先要解决error。 关于这个未连接预编译对象,一开始查到的是说要我重新编译原工程,然而这个办法并没有任何卵用。之后我又去问了雪晴,雪晴说她当时是把所有目录下的*.obj都给加入了附加依赖项,所以我也决定用*.obj来代替word_count.h,(之后我也查到了,其实是加入stdafx.h应该就没问题了)。

做完这一步 error没有了,测试程序编译通过但是错误接踵而至,测试程序产生了异常。不过令人欣喜的是,至少测试程序开始运行了,对吧。

接着来处理异常,如下:

 VS2015 c++程序单元测试初探——从0到1中所遇到的错误和历程
VS2015安装与C++进行简单单元测试
VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项
断言(ASSERT)的用法
Visaul Studio2015安装以及c++单元测试使用方法
带你玩转Visual Studio——单元测试
C++单元测试一:并非看上去那么简单——几个很实际的问题

上网查看了debug_heap.cpp,发现并不能解决问题,接着又查询了_CrtisValidHeapPointer(block),发现可能是内存泄漏等等的错误,这不禁让我怀疑起自己写的测试程序,于是在测试代码的短短几行里胡乱改动。。。然而在半个小时的徒劳无功下,我最后决定从warning入手。

我首先重新搜索了忽略/EDITANDCONTINUE,但是没有找到端倪。后来在无意中,我看到有篇博客中专门提到需要忽略下面的warning中的两个lib,MSVCRT和UCRTb,然而我在生成测试时,发现IDE似乎在哪里说过了忽略这两个库,这导致我以为这个问题系统已经自动解决(毕竟报的是warning),于是我又浪费了15分钟在怀疑自己和程序上,最后我特意把这两句话上网百度后,发现一篇博客里讲述的一个莫名其妙(因为我不懂)的方法,就是右键TestProject1à属性àC/C++à生成代码à运行库 中改为另一个(MDàMT),见图:

 VS2015 c++程序单元测试初探——从0到1中所遇到的错误和历程
VS2015安装与C++进行简单单元测试
VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项
断言(ASSERT)的用法
Visaul Studio2015安装以及c++单元测试使用方法
带你玩转Visual Studio——单元测试
C++单元测试一:并非看上去那么简单——几个很实际的问题

VS2015 c++程序单元测试初探——从0到1中所遇到的错误和历程
VS2015安装与C++进行简单单元测试
VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项
断言(ASSERT)的用法
Visaul Studio2015安装以及c++单元测试使用方法
带你玩转Visual Studio——单元测试
C++单元测试一:并非看上去那么简单——几个很实际的问题

于是我就尝试了一下,但是失败了,于是我把四个选项都尝试了一遍,终于在MDd的状态下,测试继续进行了!而且,总算是显示了测试资源管理器,里面发现测试成功了!下面上一个测试失败的样例和成功的样例(上为失败,下为成功),可以看到失败的原因是因为assert()被设置成了!=,但实际上应该是等于。

 VS2015 c++程序单元测试初探——从0到1中所遇到的错误和历程
VS2015安装与C++进行简单单元测试
VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项
断言(ASSERT)的用法
Visaul Studio2015安装以及c++单元测试使用方法
带你玩转Visual Studio——单元测试
C++单元测试一:并非看上去那么简单——几个很实际的问题

 VS2015 c++程序单元测试初探——从0到1中所遇到的错误和历程
VS2015安装与C++进行简单单元测试
VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项
断言(ASSERT)的用法
Visaul Studio2015安装以及c++单元测试使用方法
带你玩转Visual Studio——单元测试
C++单元测试一:并非看上去那么简单——几个很实际的问题

至此,这说明我的第一次单元测试的尝试已经完成了!虽然测试的是一个无关痛痒的功能,但是至少完成了从0到1的转变,令人激动!

感想

事实证明,第一次用一样东西最痛苦的就是报错了你都不知道他是为啥,在哪查,连他到底在干什么都不知道,所以从0到1真的需要最大的精力和耐心。

首先,我一直在怀疑测试代码有问题,甚至到最后都在怀疑是不是我的链接过程还是有问题,但是这些怀疑没有来源,所以不可靠。但我却没有关注warning,对warning的查询虽然不是没有。但是就是草草看了一眼就断定不是(应该给自己一巴掌),以后真的一定要有清理warning的习惯啊!

下面附上一些有用的资料:

VS2015 使用微软自带的单元测试框架测试本地C++代码的注意事项

如果测试类使用了预编译头文件的话,要在工程设置中添加stdafx.obj

测试STL容器时,会弹出异常错误对话框.解决办法是忽略MSVCRT.lib 和UCRT.lib

Assert类:

单元测试中Assert类,单元测试Assert类

Assert.AreEqual方法:

https://msdn.microsoft.com/zh-cn/library/microsoft.visualstudio.testtools.unittesting.assert.areequal(VS.80).aspx

StringAssert方法:

https://msdn.microsoft.com/zh-cn/library/microsoft.visualstudio.testtools.unittesting.stringassert.aspx

 

其他教程:

Visaul Studio2015安装以及c++单元测试使用方法

带你玩转Visual Studio——单元测试

一个关于单元测试未解决的问题:

C++单元测试一:并非看上去那么简单——几个很实际的问题