第三十一天
今早单词背的比较顺利,虽然不知道有没有用
决定早上进行每日任务,下午推主线——也许我只是不想写zmq代码罢了
早上
第四个例子就是个计数器的增减实验,从C++代码到Gtest使用都没有什么可圈可点的地方,唯一一个注意一点:EXPECT_EQ只会检查一次参数,而且是输入的参数的值,有的时候我们总把输入的参数当成我们“期望的结果”,就比如在这个例子中,每次检查后,实际的计数器都并不等于计数器当前的值,在使用或者编写的时候应该注意。
sample4.h
// A sample program demonstrating using Google C++ testing framework.
#ifndef GTEST_SAMPLES_SAMPLE4_H_
#define GTEST_SAMPLES_SAMPLE4_H_
// A simple monotonic counter.
class Counter {
private:
int counter_;
public:
// Creates a counter that starts at 0.
Counter() : counter_(0) {}
// Returns the current counter value, and increments it.
int Increment();
// Returns the current counter value, and decrements it.
int Decrement();
// Prints the current counter value to STDOUT.
void Print() const;
};
#endif // GTEST_SAMPLES_SAMPLE4_H_
sample4.cc
// A sample program demonstrating using Google C++ testing framework.
#include <stdio.h>
#include "sample4.h"
// Returns the current counter value, and increments it.
int Counter::Increment() {
return counter_++;
}
// Returns the current counter value, and decrements it.
// counter can not be less than 0, return 0 in this case
int Counter::Decrement() {
if (counter_ == 0) {
return counter_;
} else {
return counter_--;
}
}
// Prints the current counter value to STDOUT.
void Counter::Print() const {
printf("%d", counter_);
}
sample4_unittest.c
#include "sample4.h"
#include "gtest/gtest.h"
namespace {
// Tests the Increment() method.
TEST(Counter, Increment) {
Counter c;
// Test that counter 0 returns 0
EXPECT_EQ(0, c.Decrement());
// EXPECT_EQ() evaluates its arguments exactly once, so they
// can have side effects.
EXPECT_EQ(0, c.Increment());
EXPECT_EQ(1, c.Increment());
EXPECT_EQ(2, c.Increment());
EXPECT_EQ(3, c.Decrement());
}
} // namespace
这个太简单了,就再学习一下第五个例子吧。
从第五个例子开始,它所使用的头文件就都是前面定义过的了,主要是一些功能性的用法,第五个官方注释里没有小技巧,我就自己总结一下它干了点啥吧。
Gtest 小技巧 - 5:父子夹具的使用
使用夹具时,如果你只是针对某一种特定的测试设计,那么显然它只能适应与一种测试的要求。但不要忘记,夹具也是类,意味着我们可以在此使用前面公用代码逻辑的思想,把公用部分放到“父夹具”里,然后派生出功能更加具体的“子夹具”。然后在添加其他类似的夹具时,你就可以直接继承父夹具的功能,然后稍加修饰即可,这本质上是类的操作。
下面的这个例子中,父夹具是一个计时功能,子夹具是各个测试的具体功能,这样的结构可以让各个测试在使用时都知道自己花了多久,而不用每个都再编一遍。
sample5_unittest.c
#include <limits.h>
#include <time.h>
#include "gtest/gtest.h"
#include "sample1.h"
#include "sample3-inl.h"
namespace {
class QuickTest : public testing::Test {
protected:
// Remember that SetUp() is run immediately before a test starts.
// This is a good place to record the start time.
void SetUp() override { start_time_ = time(nullptr); }
// TearDown() is invoked immediately after a test finishes. Here we
// check if the test was too slow.
void TearDown() override {
// Gets the time when the test finishes
const time_t end_time = time(nullptr);
// Asserts that the test took no more than ~5 seconds. Did you
// know that you can use assertions in SetUp() and TearDown() as
// well?
EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long.";
}
// The UTC time (in seconds) when the test starts
time_t start_time_;
};
// We derive a fixture named IntegerFunctionTest from the QuickTest
// fixture. All tests using this fixture will be automatically
// required to be quick.
class IntegerFunctionTest : public QuickTest {
// We don't need any more logic than already in the QuickTest fixture.
// Therefore the body is empty.
};
// Now we can write tests in the IntegerFunctionTest test case.
// Tests Factorial()
TEST_F(IntegerFunctionTest, Factorial) {
// Tests factorial of negative numbers.
EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(1, Factorial(-1));
EXPECT_GT(Factorial(-10), 0);
// Tests factorial of 0.
EXPECT_EQ(1, Factorial(0));
// Tests factorial of positive numbers.
EXPECT_EQ(1, Factorial(1));
EXPECT_EQ(2, Factorial(2));
EXPECT_EQ(6, Factorial(3));
EXPECT_EQ(40320, Factorial(8));
}
// Tests IsPrime()
TEST_F(IntegerFunctionTest, IsPrime) {
// Tests negative input.
EXPECT_FALSE(IsPrime(-1));
EXPECT_FALSE(IsPrime(-2));
EXPECT_FALSE(IsPrime(INT_MIN));
// Tests some trivial cases.
EXPECT_FALSE(IsPrime(0));
EXPECT_FALSE(IsPrime(1));
EXPECT_TRUE(IsPrime(2));
EXPECT_TRUE(IsPrime(3));
// Tests positive input.
EXPECT_FALSE(IsPrime(4));
EXPECT_TRUE(IsPrime(5));
EXPECT_FALSE(IsPrime(6));
EXPECT_TRUE(IsPrime(23));
}
class QueueTest : public QuickTest {
protected:
void SetUp() override {
// First, we need to set up the super fixture (QuickTest).
QuickTest::SetUp();
// Second, some additional setup for this fixture.
q1_.Enqueue(1);
q2_.Enqueue(2);
q2_.Enqueue(3);
}
// By default, TearDown() inherits the behavior of
// QuickTest::TearDown(). As we have no additional cleaning work
// for QueueTest, we omit it here.
//
// virtual void TearDown() {
// QuickTest::TearDown();
// }
Queue<int> q0_;
Queue<int> q1_;
Queue<int> q2_;
};
// Now, let's write tests using the QueueTest fixture.
// Tests the default constructor.
TEST_F(QueueTest, DefaultConstructor) {
EXPECT_EQ(0u, q0_.Size());
}
// Tests Dequeue().
TEST_F(QueueTest, Dequeue) {
int* n = q0_.Dequeue();
EXPECT_TRUE(n == nullptr);
n = q1_.Dequeue();
EXPECT_TRUE(n != nullptr);
EXPECT_EQ(1, *n);
EXPECT_EQ(0u, q1_.Size());
delete n;
n = q2_.Dequeue();
EXPECT_TRUE(n != nullptr);
EXPECT_EQ(2, *n);
EXPECT_EQ(1u, q2_.Size());
delete n;
}
} // namespace
再练练写作吧.
下午
果然,我的大脑十分抗拒写代码和思考,en,慢得要死。
初写czmq的一些收获:
- 一个非常基础的东西,结果今天翻czmq文档的时候才看到,非常惭愧:
- 初步用了几个czmq的API,是比cmq能舒服一点,希望之后能舒服很多。
- 第一次用了 zstr_recv API 注意他会自动申请对应内存,算是比较方便的了,但一定要记得删掉,不然内存泄漏。
czmq 初尝试: