Google Mock - GoogleTest(九)

2023-11-10

本文翻译自:https://github.com/google/googletest/blob/master/googlemock/docs/CheatSheet.md

一、定义一个模拟类

1. 模拟一个正常的类,就是接口类

  给:

1

2

3

4

5

6

7

8

class Foo {

  ...

  virtual ~Foo();

  virtual int GetSize() const = 0;

  virtual string Describe(const char* name) = 0;

  virtual string Describe(int type) = 0;

  virtual bool Process(Bar elem, int count) = 0;

};

(note that ~Foo() must be virtual) we can define its mock as,定义模拟类。

1

2

3

4

5

6

7

8

#include "gmock/gmock.h"

class MockFoo : public Foo {

  MOCK_CONST_METHOD0(GetSize, int());

  MOCK_METHOD1(Describe, string(const char* name));

  MOCK_METHOD1(Describe, string(int type));

  MOCK_METHOD2(Process, bool(Bar elem, int count));

};

创建一个“nice”模拟对象忽略所有无趣的调用,或一个“strict”模拟对象,将它们视为失败:

1

2

NiceMock<MockFoo> nice_foo;     // The type is a subclass of MockFoo.

StrictMock<MockFoo> strict_foo; // The type is a subclass of MockFoo.

2. 模拟一个类模板

To mock:

1

2

3

4

5

6

7

8

template <typename Elem>

class StackInterface {

 public:

  ...

  virtual ~StackInterface();

  virtual int GetSize() const = 0;

  virtual void Push(const Elem& x) = 0;

};

(note that ~StackInterface() must be virtual) just append _T to the MOCK_* macros:

1

2

3

4

5

6

7

template <typename Elem>

class MockStack : public StackInterface<Elem> {

 public:

  ...

  MOCK_CONST_METHOD0_T(GetSize, int());

  MOCK_METHOD1_T(Push, void(const Elem& x));

};

3. 指定模拟函数的调用约定

如果您的mock函数不使用默认调用约定,您可以通过将_WITH_CALLTYPE附加到前两个部分中描述的任何宏并指定调用约定作为宏的第一个参数来指定它。例如,

1

2

MOCK_METHOD_1_WITH_CALLTYPE(STDMETHODCALLTYPE,Foo,boolint n));

MOCK_CONST_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,Bar,intdouble x,double y));​ 

其中STDMETHODCALLTYPE由Windows上的<objbase.h>定义。

二、在测试中使用模拟器

典型的流程是:

  1. 导入您需要使用的Google Mock名称。所有Google Mock名称都位于测试命名空间中,除非它们是宏或其他注释。
  2. 创建模拟对象。
  3. (可选)设置模拟对象的默认操作。
  4. 设置你对模拟对象的期望(他们怎么叫?他们做什么?)。
  5. 使用模拟对象的练习代码;如有必要,请使用Google Test断言检查结果。
  6. 当模拟对象被破坏时,Google Mock会自动验证所有对其的期望是否满足。

这里是一个例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

using ::testing::Return;                            // #1

TEST(BarTest, DoesThis) {

  MockFoo foo;                                    // #2

  ON_CALL(foo, GetSize())                         // #3

      .WillByDefault(Return(1));

  // ... other default actions ...

  EXPECT_CALL(foo, Describe(5))                   // #4

      .Times(3)

      .WillRepeatedly(Return("Category 5"));

  // ... other expectations ...

  EXPECT_EQ("good", MyProductionFunction(&foo));  // #5

}                                                 // #6

三、设置默认操作

Google Mock对任何返回void,bool,数值或指针的函数都有一个内置的默认动作。

要为全局返回类型T的函数自定义默认操作:

1

2

3

4

5

6

7

8

9

10

using ::testing::DefaultValue;

// Sets the default value to be returned. T must be CopyConstructible.

DefaultValue<T>::Set(value);

// Sets a factory. Will be invoked on demand. T must be MoveConstructible.

//   T MakeT();

DefaultValue<T>::SetFactory(&MakeT);

// ... use the mocks ...

// Resets the default value.

DefaultValue<T>::Clear();

要自定义特定方法的默认操作,请使用ON_CALL():

1

2

3

ON_CALL(mock_object, method(matchers))

    .With(multi_argument_matcher)  ?

    .WillByDefault(action);

四、设置期望

EXPECT_CALL()在模拟方法上设置期望(如何调用它?它会做什么?):

1

2

3

4

5

6

7

8

EXPECT_CALL(mock_object, method(matchers))

    .With(multi_argument_matcher)  ?

    .Times(cardinality)            ?

    .InSequence(sequences)         *

    .After(expectations)           *

    .WillOnce(action)              *

    .WillRepeatedly(action)        ?

    .RetiresOnSaturation();        ?

如果省略Times(),则基数假定为:

  • Times(1)当没有WillOnce()和WillRepeatedly();
  • 当有n个WillOnce()但没有WillRepeatedly()时,Times(n),其中n> = 1; 要么
  • 当有n个WillOnce()和WillRepeatedly(),其中n> = 0时,Times(AtLeast(n))。

没有EXPECT_CALL()的方法可以被任意调用多次,并且每次都将采取默认操作。

五、匹配

匹配器匹配单个参数。 您可以在ON_CALL()或EXPECT_CALL()中使用它,或使用它直接验证值:

EXPECT_THAT(value, matcher) Asserts that value matches matcher.
ASSERT_THAT(value, matcher) The same as EXPECT_THAT(value, matcher), except that it generates a fatal failure.

内置的匹配(其中参数是函数参数)分为几类:

1. 通配符

_ argument can be any value of the correct type可以代表任意类型.
A<type>() or An<type>() argument can be any value of type可以是type类型的任意值.

2. 一般比较

Eq(value) 或者 value argument == value,method中的形参必须是value
Ge(value) argument >= value,method中的形参必须大于等于value
Gt(value) argument > value
Le(value) argument <= value
Lt(value) argument < value
Ne(value) argument != value
IsNull() method的形参必须是NULL指针
NotNull() argument is a non-null pointer
Ref(variable) 形参是variable的引用
TypedEq<type>(value) 形参的类型必须是type类型,而且值必须是value。当模拟函数被重载你可能需要它而不是Eq(vlaue)

注意** 除了Ref()之外,这些匹配器会创建一个值的副本,以备日后修改或销毁。 如果编译器抱怨该值没有公共副本构造函数,请尝试将其包装在ByRef()中,例如。 Eq(ByRef(non_copyable_value))。 如果你这样做,请确保non_copyable_value之后不改变,否则你的匹配器的含义将被改变。

3. 浮点数的比较

DoubleEq(a_double) 形参是一个double类型,比如值近似于a_double,两个NaN是不相等的
FloatEq(a_float) 同上,只不过类型是float
NanSensitiveDoubleEq(a_double) 形参是一个double类型,比如值近似于a_double,两个NaN是相等的,这个是用户所希望的方式
NanSensitiveFloatEq(a_float) 同上,只不过形参是float

上述匹配器使用基于ULP的比较(与Google Test中使用的比较相同)。 它们根据期望值的绝对值自动选择合理的误差界限。 DoubleEq()和FloatEq()符合IEEE标准,这需要比较两个NaNs的相等性返回false。 NanSensitive *版本将两个NaNs相等,这通常是用户想要的。

DoubleNear(a_double, max_abs_error) argument is a double value close to a_double (absolute error <= max_abs_error), treating two NaNs as unequal.
FloatNear(a_float, max_abs_error) argument is a float value close to a_float (absolute error <= max_abs_error), treating two NaNs as unequal.
NanSensitiveDoubleNear(a_double, max_abs_error) argument is a double value close to a_double (absolute error <= max_abs_error), treating two NaNs as equal.
NanSensitiveFloatNear(a_float, max_abs_error) argument is a float value close to a_float (absolute error <= max_abs_error), treating two NaNs as equal.

4. String Matchers

这里的字符串即可以是C风格的字符串,也可以是C++风格的。

ContainsRegex(string) 形参匹配给定的正则表达式
EndsWith(suffix) 形参以suffix截尾
HasSubstr(string) 形参有string这个子串
MatchesRegex(string) 从第一个字符到最后一个字符都完全匹配给定的正则表达式.
StartsWith(prefix) 形参以prefix开始
StrCaseEq(string) 参数等于string,并且忽略大小写
StrCaseNe(string) 参数不是string,并且忽略大小写
StrEq(string) 参数等于string
StrNe(string) 参数不等于string

5. 容器的匹配

很多STL的容器的比较都支持==这样的操作,对于这样的容器可以使用上述的Eq(expected_container)来比较或者只是expect_container来完全匹配容器。但如果你想写得更为灵活,可以使用下面的这些容器匹配方法:

ContainerEq(container) The same as Eq(container) except that the failure message also includes which elements are in one container but not the other.
Contains(e) argument contains an element that matches e, which can be either a value or a matcher.
Each(e) argument is a container where every element matches e, which can be either a value or a matcher.
ElementsAre(e0, e1, ..., en) argument has n + 1 elements, where the i-th element matches ei, which can be a value or a matcher. 0 to 10 arguments are allowed.
ElementsAreArray({ e0, e1, ..., en })ElementsAreArray(array), or ElementsAreArray(array, count) The same as ElementsAre() except that the expected element values/matchers come from an initializer list, STL-style container, or C-style array.
IsEmpty() argument is an empty container (container.empty()).
Pointwise(m, container) argument contains the same number of elements as in container, and for all i, (the i-th element in argument, the i-th element in container) match m, which is a matcher on 2-tuples. E.g. Pointwise(Le(), upper_bounds) verifies that each element in argument doesn't exceed the corresponding element in upper_bounds. See more detail below.
SizeIs(m) argument is a container whose size matches m. E.g. SizeIs(2) or SizeIs(Lt(2)).
UnorderedElementsAre(e0, e1, ..., en) argument has n + 1 elements, and under some permutation each element matches an ei (for a different i), which can be a value or a matcher. 0 to 10 arguments are allowed.
UnorderedElementsAreArray({ e0, e1, ..., en })UnorderedElementsAreArray(array), or UnorderedElementsAreArray(array, count) The same as UnorderedElementsAre() except that the expected element values/matchers come from an initializer list, STL-style container, or C-style array.
WhenSorted(m) When argument is sorted using the < operator, it matches container matcher m. E.g. WhenSorted(UnorderedElementsAre(1, 2, 3)) verifies that argument contains elements 12, and 3, ignoring order.
WhenSortedBy(comparator, m) The same as WhenSorted(m), except that the given comparator instead of < is used to sort argument. E.g. WhenSortedBy(std::greater<int>(), ElementsAre(3, 2, 1)).

注意:

  • 这些匹配器也可以匹配:

     i. 通过引用传递的本地数组(例如在Foo(const int(&a)[5])中)和

     ii. 作为指针和计数传递的数组(例如,在Bar(const T * buffer,int len) - 参见 Multi-argument Matchers)。

  • 匹配的数组可以是多维的(即其元素可以是数组)。

  • 在Pointwise(m,...)中的m应该是:: testing :: tuple <T,U>的匹配器,其中T和U分别是实际容器和预期容器的元素类型。 例如,要比较两个Foo容器,其中Foo不支持operator ==但是有一个Equals()方法,可以写:

1

2

3

4

5

6

using ::testing::get;

MATCHER(FooEq, "") {

  return get<0>(arg).Equals(get<1>(arg));

}

...

EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos));

6. 成员匹配器

Field(&class::field, m) argument.field (or argument->field when argument is a plain pointer) matches matcher m, where argument is an object of type class.
Key(e) argument.first matches e, which can be either a value or a matcher. E.g. Contains(Key(Le(5))) can verify that a map contains a key <= 5.
Pair(m1, m2) argument is an std::pair whose first field matches m1 and second field matches m2.
Property(&class::property, m) argument.property() (or argument->property() when argument is a plain pointer) matches matcher m, where argument is an object of type class.

7. 匹配函数或函数的结果

 8. 指针匹配

Pointee(m)

argument (either a smart pointer or a raw pointer) points to a value that matches matcher m.

WhenDynamicCastTo<T>(m)

when argument is passed through dynamic_cast<T>(), it matches matcher m.

 9. 多参数匹配器

从技术上讲,完全匹配器匹配单个值。 “多参数”匹配器只是匹配元组的匹配器。 以下匹配器可用于匹配元组(x,y):

Eq() x == y
Ge() x >= y
Gt() x > y
Le() x <= y
Lt() x < y
Ne() x != y

您可以使用以下选择器来选择参数的子集(或对其重新排序)以参与匹配:

AllArgs(m) Equivalent to m. Useful as syntactic sugar in .With(AllArgs(m)).
Args<N1, N2, ..., Nk>(m) The tuple of the k selected (using 0-based indices) arguments matches m, e.g. Args<1, 2>(Eq()).

10. 复合匹配

你可以从一个或多个其他匹配器做一个匹配器:

AllOf(m1, m2, ..., mn) argument matches all of the matchers m1 to mn.
AnyOf(m1, m2, ..., mn) argument matches at least one of the matchers m1 to mn.
Not(m) argument doesn't match matcher m.

11. Adapters for Matchers

MatcherCast<T>(m) casts matcher m to type Matcher<T>.
SafeMatcherCast<T>(m) safely casts matcher m to type Matcher<T>.
Truly(predicate) predicate(argument) returns something considered by C++ to be true, where predicate is a function or functor.

12 .匹配作为谓词(Matchers as Predicates)

Matches(m)(value) evaluates to true if value matches m. You can use Matches(m) alone as a unary functor.
ExplainMatchResult(m, value, result_listener) evaluates to true if value matches m, explaining the result to result_listener.
Value(value, m) evaluates to true if value matches m.

13. 定义匹配

MATCHER(IsEven, "") { return (arg % 2) == 0; } Defines a matcher IsEven() to match an even number.
MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; } Defines a macher IsDivisibleBy(n) to match a number divisible by n.
MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; } Defines a matcher IsBetween(a, b) to match a value in the range [ab].

笔记:

  1. MATCHER *宏不能在函数或类中使用。
  2. 匹配器主体必须是纯功能性的(即它不能有任何副作用,并且结果必须不依赖于被匹配的值和匹配器参数之外的任何东西)。
  3. 您可以使用PrintToString(x)将任何类型的值x转换为字符串。

14. 匹配作为测试断言

ASSERT_THAT(expression, m) Generates a fatal failure if the value of expression doesn't match matcher m.
EXPECT_THAT(expression, m) Generates a non-fatal failure if the value of expression doesn't match matcher m.

六、动作Actions

操作指定了mock函数在调用时应该执行的操作。

1. 返回值

Return() Return from a void mock function.
Return(value) Return value. If the type of value is different to the mock function's return type, value is converted to the latter type at the time the expectation is set, not when the action is executed.
ReturnArg<N>() Return the N-th (0-based) argument.
ReturnNew<T>(a1, ..., ak) Return new T(a1, ..., ak); a different object is created each time.
ReturnNull() Return a null pointer.
ReturnPointee(ptr) Return the value pointed to by ptr.
ReturnRef(variable) Return a reference to variable.
ReturnRefOfCopy(value) Return a reference to a copy of value; the copy lives as long as the action.

2. 副作用(Side Effects)

Assign(&variable, value) Assign value to variable.
DeleteArg<N>() Delete the N-th (0-based) argument, which must be a pointer.
SaveArg<N>(pointer) Save the N-th (0-based) argument to *pointer.
SaveArgPointee<N>(pointer) Save the value pointed to by the N-th (0-based) argument to *pointer.
SetArgReferee<N>(value) Assign value to the variable referenced by the N-th (0-based) argument.
SetArgPointee<N>(value) Assign value to the variable pointed by the N-th (0-based) argument.
SetArgumentPointee<N>(value) Same as SetArgPointee<N>(value). Deprecated. Will be removed in v1.7.0.
SetArrayArgument<N>(first, last) Copies the elements in source range [firstlast) to the array pointed to by the N-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range.
SetErrnoAndReturn(error, value) Set errno to error and return value.
Throw(exception) Throws the given exception, which can be any copyable value. Available since v1.1.0.

3. 使用函数或函子作为动作Using a Function or a Functor as an Action

Invoke(f) Invoke f with the arguments passed to the mock function, where f can be a global/static function or a functor.
Invoke(object_pointer, &class::method) Invoke the {method on the object with the arguments passed to the mock function.
InvokeWithoutArgs(f) Invoke f, which can be a global/static function or a functor. f must take no arguments.
InvokeWithoutArgs(object_pointer, &class::method) Invoke the method on the object, which takes no arguments.
InvokeArgument<N>(arg1, arg2, ..., argk) Invoke the mock function's N-th (0-based) argument, which must be a function or a functor, with the k arguments.

被调用函数的返回值被用作动作的返回值。
定义要与Invoke *()一起使用的函数或函数时,可以将任何未使用的参数声明为未使用:

1

2

3

double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); }

  ...

EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance));

在Invoke Argument <N>(...)中,如果一个参数需要通过引用传递,则将其包装在ByRef()中。 例如,

1

InvokeArgument<2>(5, string("Hi"), ByRef(foo))

调用模拟函数#2参数,通过值传递给它5和字符串(“Hi”),并通过引用传递foo。

Default Action

Note: due to technical reasons, DoDefault() cannot be used inside a composite action - trying to do so will result in a run-time error.

Composite Actions

DoAll(a1, a2, ..., an) Do all actions a1 to an and return the result of an in each invocation. The first n - 1sub-actions must return void.
IgnoreResult(a) Perform action a and ignore its result. a must not return void.
WithArg<N>(a) Pass the N-th (0-based) argument of the mock function to action a and perform it.
WithArgs<N1, N2, ..., Nk>(a) Pass the selected (0-based) arguments of the mock function to action a and perform it.
WithoutArgs(a) Perform action a without any arguments.

Defining Actions

ACTION(Sum) { return arg0 + arg1; } Defines an action Sum() to return the sum of the mock function's argument #0 and #1.
ACTION_P(Plus, n) { return arg0 + n; } Defines an action Plus(n) to return the sum of the mock function's argument #0 and n.
ACTION_Pk(Foo, p1, ..., pk) { statements; } Defines a parameterized action Foo(p1, ..., pk) to execute the given statements.

The ACTION* macros cannot be used inside a function or class.

七、Cardinalities基数

这些在Times()中用于指定将调用模拟函数的次数:

AnyNumber() The function can be called any number of times.
AtLeast(n) The call is expected at least n times.
AtMost(n) The call is expected at most n times.
Between(m, n) The call is expected between m and n (inclusive) times.
Exactly(n) or n The call is expected exactly n times. In particular, the call should never happen when n is 0.

八、期望顺序(Expectation Order)

默认情况下,期望可以按任何顺序匹配。如果一些或所有期望必须在给定的顺序中匹配,则有两种方式来指定它们。 它们可以单独使用或一起使用。

1.The After Clause

1

2

3

4

5

6

using ::testing::Expectation;

...

Expectation init_x = EXPECT_CALL(foo, InitX());

Expectation init_y = EXPECT_CALL(foo, InitY());

EXPECT_CALL(foo, Bar())

    .After(init_x, init_y);

上边说,只有在InitX()和InitY()被调用之后才能调用Bar()。

如果你不知道你写的期望有多少个前提条件,你可以使用ExpectationSet来收集它们:

1

2

3

4

5

6

7

8

using ::testing::ExpectationSet;

...

ExpectationSet all_inits;

for (int i = 0; i < element_count; i++) {

  all_inits += EXPECT_CALL(foo, InitElement(i));

}

EXPECT_CALL(foo, Bar())

    .After(all_inits);

上面说,只有在所有元素都被初始化之后才能调用Bar()。(但我们不关心哪些元素在其他元素之前被初始化)。

在 .After(all_inits)​中使用ExpectationSet之后再修改ExpectationSet不会影响.After()的含义。

2. 序列

当你有一个长链的顺序期望,使用序列指定顺序更容易,这不需要给链中的每个期望一个不同的名称。同一序列中的所有预期调用必须按其指定的顺序发生。

1

2

3

4

5

6

7

8

9

10

11

12

using ::testing::Sequence;

Sequence s1, s2;

...

EXPECT_CALL(foo, Reset())

    .InSequence(s1, s2)

    .WillOnce(Return(true));

EXPECT_CALL(foo, GetSize())

    .InSequence(s1)

    .WillOnce(Return(1));

EXPECT_CALL(foo, Describe(A<const char*>()))

    .InSequence(s2)

    .WillOnce(Return("dummy"));

上边说,Reset()必须在GetSize()和Describe()之前调用,后两个可以以任何顺序发生。

在一个序列中方便地提出许多期望:

1

2

3

4

5

6

7

8

9

using ::testing::InSequence;

{

  InSequence dummy;

  EXPECT_CALL(...)...;

  EXPECT_CALL(...)...;

  ...

  EXPECT_CALL(...)...;

}

上边说,在dummy范围内的所有预期调用必须以严格的顺序发生。 名称dummy是不相关的。)

九、验证和重置模拟

Google Mock会在模拟对象被破坏时验证对模拟对象的期望,或者您可以更早地执行:

1

2

3

4

5

6

7

8

9

10

using ::testing::Mock;

...

// Verifies and removes the expectations on mock_obj;

// returns true iff successful.

Mock::VerifyAndClearExpectations(&mock_obj);

...

// Verifies and removes the expectations on mock_obj;

// also removes the default actions set by ON_CALL();

// returns true iff successful.

Mock::VerifyAndClear(&mock_obj);

您还可以告诉Google Mock模拟对象可以泄漏,无需进行验证:

1

Mock::AllowLeak(&mock_obj);

十、模拟类

Google Mock定义了一个方便的模拟类模板

1

2

3

4

class MockFunction<R(A1, ..., An)> {

 public:

  MOCK_METHODn(Call, R(A1, ..., An));

};

---恢复内容结束---

CheatSheet文档中包含了GMock所有常用的东西,看了这个基本上就可以用它了,本文翻译自:https://github.com/google/googletest/blob/master/googlemock/docs/CheatSheet.md

一、定义一个模拟类

1. 模拟一个正常的类,就是接口类

  给:

1

2

3

4

5

6

7

8

class Foo {

  ...

  virtual ~Foo();

  virtual int GetSize() const = 0;

  virtual string Describe(const char* name) = 0;

  virtual string Describe(int type) = 0;

  virtual bool Process(Bar elem, int count) = 0;

};

(note that ~Foo() must be virtual) we can define its mock as,定义模拟类。

1

2

3

4

5

6

7

8

#include "gmock/gmock.h"

class MockFoo : public Foo {

  MOCK_CONST_METHOD0(GetSize, int());

  MOCK_METHOD1(Describe, string(const char* name));

  MOCK_METHOD1(Describe, string(int type));

  MOCK_METHOD2(Process, bool(Bar elem, int count));

};

创建一个“nice”模拟对象忽略所有无趣的调用,或一个“strict”模拟对象,将它们视为失败:

1

2

NiceMock<MockFoo> nice_foo;     // The type is a subclass of MockFoo.

StrictMock<MockFoo> strict_foo; // The type is a subclass of MockFoo.

2. 模拟一个类模板

To mock:

1

2

3

4

5

6

7

8

template <typename Elem>

class StackInterface {

 public:

  ...

  virtual ~StackInterface();

  virtual int GetSize() const = 0;

  virtual void Push(const Elem& x) = 0;

};

(note that ~StackInterface() must be virtual) just append _T to the MOCK_* macros:

1

2

3

4

5

6

7

template <typename Elem>

class MockStack : public StackInterface<Elem> {

 public:

  ...

  MOCK_CONST_METHOD0_T(GetSize, int());

  MOCK_METHOD1_T(Push, void(const Elem& x));

};

3. 指定模拟函数的调用约定

如果您的mock函数不使用默认调用约定,您可以通过将_WITH_CALLTYPE附加到前两个部分中描述的任何宏并指定调用约定作为宏的第一个参数来指定它。例如,

1

2

MOCK_METHOD_1_WITH_CALLTYPE(STDMETHODCALLTYPE,Foo,boolint n));

MOCK_CONST_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,Bar,intdouble x,double y));​ 

其中STDMETHODCALLTYPE由Windows上的<objbase.h>定义。

二、在测试中使用模拟器

典型的流程是:

  1. 导入您需要使用的Google Mock名称。所有Google Mock名称都位于测试命名空间中,除非它们是宏或其他注释。
  2. 创建模拟对象。
  3. (可选)设置模拟对象的默认操作。
  4. 设置你对模拟对象的期望(他们怎么叫?他们做什么?)。
  5. 使用模拟对象的练习代码;如有必要,请使用Google Test断言检查结果。
  6. 当模拟对象被破坏时,Google Mock会自动验证所有对其的期望是否满足。

这里是一个例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

using ::testing::Return;                            // #1

TEST(BarTest, DoesThis) {

  MockFoo foo;                                    // #2

  ON_CALL(foo, GetSize())                         // #3

      .WillByDefault(Return(1));

  // ... other default actions ...

  EXPECT_CALL(foo, Describe(5))                   // #4

      .Times(3)

      .WillRepeatedly(Return("Category 5"));

  // ... other expectations ...

  EXPECT_EQ("good", MyProductionFunction(&foo));  // #5

}                                                 // #6

三、设置默认操作

Google Mock对任何返回void,bool,数值或指针的函数都有一个内置的默认动作。

要为全局返回类型T的函数自定义默认操作:

1

2

3

4

5

6

7

8

9

10

using ::testing::DefaultValue;

// Sets the default value to be returned. T must be CopyConstructible.

DefaultValue<T>::Set(value);

// Sets a factory. Will be invoked on demand. T must be MoveConstructible.

//   T MakeT();

DefaultValue<T>::SetFactory(&MakeT);

// ... use the mocks ...

// Resets the default value.

DefaultValue<T>::Clear();

要自定义特定方法的默认操作,请使用ON_CALL():

1

2

3

ON_CALL(mock_object, method(matchers))

    .With(multi_argument_matcher)  ?

    .WillByDefault(action);

四、设置期望

EXPECT_CALL()在模拟方法上设置期望(如何调用它?它会做什么?):

1

2

3

4

5

6

7

8

EXPECT_CALL(mock_object, method(matchers))

    .With(multi_argument_matcher)  ?

    .Times(cardinality)            ?

    .InSequence(sequences)         *

    .After(expectations)           *

    .WillOnce(action)              *

    .WillRepeatedly(action)        ?

    .RetiresOnSaturation();        ?

如果省略Times(),则基数假定为:

  • Times(1)当没有WillOnce()和WillRepeatedly();
  • 当有n个WillOnce()但没有WillRepeatedly()时,Times(n),其中n> = 1; 要么
  • 当有n个WillOnce()和WillRepeatedly(),其中n> = 0时,Times(AtLeast(n))。

没有EXPECT_CALL()的方法可以被任意调用多次,并且每次都将采取默认操作。

五、匹配

匹配器匹配单个参数。 您可以在ON_CALL()或EXPECT_CALL()中使用它,或使用它直接验证值:

EXPECT_THAT(value, matcher) Asserts that value matches matcher.
ASSERT_THAT(value, matcher) The same as EXPECT_THAT(value, matcher), except that it generates a fatal failure.

内置的匹配(其中参数是函数参数)分为几类:

1. 通配符

_ argument can be any value of the correct type可以代表任意类型.
A<type>() or An<type>() argument can be any value of type可以是type类型的任意值.

2. 一般比较

Eq(value) 或者 value argument == value,method中的形参必须是value
Ge(value) argument >= value,method中的形参必须大于等于value
Gt(value) argument > value
Le(value) argument <= value
Lt(value) argument < value
Ne(value) argument != value
IsNull() method的形参必须是NULL指针
NotNull() argument is a non-null pointer
Ref(variable) 形参是variable的引用
TypedEq<type>(value) 形参的类型必须是type类型,而且值必须是value。当模拟函数被重载你可能需要它而不是Eq(vlaue)

注意** 除了Ref()之外,这些匹配器会创建一个值的副本,以备日后修改或销毁。 如果编译器抱怨该值没有公共副本构造函数,请尝试将其包装在ByRef()中,例如。 Eq(ByRef(non_copyable_value))。 如果你这样做,请确保non_copyable_value之后不改变,否则你的匹配器的含义将被改变。

3. 浮点数的比较

DoubleEq(a_double) 形参是一个double类型,比如值近似于a_double,两个NaN是不相等的
FloatEq(a_float) 同上,只不过类型是float
NanSensitiveDoubleEq(a_double) 形参是一个double类型,比如值近似于a_double,两个NaN是相等的,这个是用户所希望的方式
NanSensitiveFloatEq(a_float) 同上,只不过形参是float

上述匹配器使用基于ULP的比较(与Google Test中使用的比较相同)。 它们根据期望值的绝对值自动选择合理的误差界限。 DoubleEq()和FloatEq()符合IEEE标准,这需要比较两个NaNs的相等性返回false。 NanSensitive *版本将两个NaNs相等,这通常是用户想要的。

DoubleNear(a_double, max_abs_error) argument is a double value close to a_double (absolute error <= max_abs_error), treating two NaNs as unequal.
FloatNear(a_float, max_abs_error) argument is a float value close to a_float (absolute error <= max_abs_error), treating two NaNs as unequal.
NanSensitiveDoubleNear(a_double, max_abs_error) argument is a double value close to a_double (absolute error <= max_abs_error), treating two NaNs as equal.
NanSensitiveFloatNear(a_float, max_abs_error) argument is a float value close to a_float (absolute error <= max_abs_error), treating two NaNs as equal.

4. String Matchers

这里的字符串即可以是C风格的字符串,也可以是C++风格的。

ContainsRegex(string) 形参匹配给定的正则表达式
EndsWith(suffix) 形参以suffix截尾
HasSubstr(string) 形参有string这个子串
MatchesRegex(string) 从第一个字符到最后一个字符都完全匹配给定的正则表达式.
StartsWith(prefix) 形参以prefix开始
StrCaseEq(string) 参数等于string,并且忽略大小写
StrCaseNe(string) 参数不是string,并且忽略大小写
StrEq(string) 参数等于string
StrNe(string) 参数不等于string

5. 容器的匹配

很多STL的容器的比较都支持==这样的操作,对于这样的容器可以使用上述的Eq(expected_container)来比较或者只是expect_container来完全匹配容器。但如果你想写得更为灵活,可以使用下面的这些容器匹配方法:

ContainerEq(container) The same as Eq(container) except that the failure message also includes which elements are in one container but not the other.
Contains(e) argument contains an element that matches e, which can be either a value or a matcher.
Each(e) argument is a container where every element matches e, which can be either a value or a matcher.
ElementsAre(e0, e1, ..., en) argument has n + 1 elements, where the i-th element matches ei, which can be a value or a matcher. 0 to 10 arguments are allowed.
ElementsAreArray({ e0, e1, ..., en })ElementsAreArray(array), or ElementsAreArray(array, count) The same as ElementsAre() except that the expected element values/matchers come from an initializer list, STL-style container, or C-style array.
IsEmpty() argument is an empty container (container.empty()).
Pointwise(m, container) argument contains the same number of elements as in container, and for all i, (the i-th element in argument, the i-th element in container) match m, which is a matcher on 2-tuples. E.g. Pointwise(Le(), upper_bounds) verifies that each element in argument doesn't exceed the corresponding element in upper_bounds. See more detail below.
SizeIs(m) argument is a container whose size matches m. E.g. SizeIs(2) or SizeIs(Lt(2)).
UnorderedElementsAre(e0, e1, ..., en) argument has n + 1 elements, and under some permutation each element matches an ei (for a different i), which can be a value or a matcher. 0 to 10 arguments are allowed.
UnorderedElementsAreArray({ e0, e1, ..., en })UnorderedElementsAreArray(array), or UnorderedElementsAreArray(array, count) The same as UnorderedElementsAre() except that the expected element values/matchers come from an initializer list, STL-style container, or C-style array.
WhenSorted(m) When argument is sorted using the < operator, it matches container matcher m. E.g. WhenSorted(UnorderedElementsAre(1, 2, 3)) verifies that argument contains elements 12, and 3, ignoring order.
WhenSortedBy(comparator, m) The same as WhenSorted(m), except that the given comparator instead of < is used to sort argument. E.g. WhenSortedBy(std::greater<int>(), ElementsAre(3, 2, 1)).

注意:

  • 这些匹配器也可以匹配:

     i. 通过引用传递的本地数组(例如在Foo(const int(&a)[5])中)和

     ii. 作为指针和计数传递的数组(例如,在Bar(const T * buffer,int len) - 参见 Multi-argument Matchers)。

  • 匹配的数组可以是多维的(即其元素可以是数组)。

  • 在Pointwise(m,...)中的m应该是:: testing :: tuple <T,U>的匹配器,其中T和U分别是实际容器和预期容器的元素类型。 例如,要比较两个Foo容器,其中Foo不支持operator ==但是有一个Equals()方法,可以写:

1

2

3

4

5

6

using ::testing::get;

MATCHER(FooEq, "") {

  return get<0>(arg).Equals(get<1>(arg));

}

...

EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos));

6. 成员匹配器

Field(&class::field, m) argument.field (or argument->field when argument is a plain pointer) matches matcher m, where argument is an object of type class.
Key(e) argument.first matches e, which can be either a value or a matcher. E.g. Contains(Key(Le(5))) can verify that a map contains a key <= 5.
Pair(m1, m2) argument is an std::pair whose first field matches m1 and second field matches m2.
Property(&class::property, m) argument.property() (or argument->property() when argument is a plain pointer) matches matcher m, where argument is an object of type class.

7. 匹配函数或函数的结果

 8. 指针匹配

Pointee(m)

argument (either a smart pointer or a raw pointer) points to a value that matches matcher m.

WhenDynamicCastTo<T>(m)

when argument is passed through dynamic_cast<T>(), it matches matcher m.

 9. 多参数匹配器

从技术上讲,完全匹配器匹配单个值。 “多参数”匹配器只是匹配元组的匹配器。 以下匹配器可用于匹配元组(x,y):

Eq() x == y
Ge() x >= y
Gt() x > y
Le() x <= y
Lt() x < y
Ne() x != y

您可以使用以下选择器来选择参数的子集(或对其重新排序)以参与匹配:

AllArgs(m) Equivalent to m. Useful as syntactic sugar in .With(AllArgs(m)).
Args<N1, N2, ..., Nk>(m) The tuple of the k selected (using 0-based indices) arguments matches m, e.g. Args<1, 2>(Eq()).

10. 复合匹配

你可以从一个或多个其他匹配器做一个匹配器:

AllOf(m1, m2, ..., mn) argument matches all of the matchers m1 to mn.
AnyOf(m1, m2, ..., mn) argument matches at least one of the matchers m1 to mn.
Not(m) argument doesn't match matcher m.

11. Adapters for Matchers

MatcherCast<T>(m) casts matcher m to type Matcher<T>.
SafeMatcherCast<T>(m) safely casts matcher m to type Matcher<T>.
Truly(predicate) predicate(argument) returns something considered by C++ to be true, where predicate is a function or functor.

12 .匹配作为谓词(Matchers as Predicates)

Matches(m)(value) evaluates to true if value matches m. You can use Matches(m) alone as a unary functor.
ExplainMatchResult(m, value, result_listener) evaluates to true if value matches m, explaining the result to result_listener.
Value(value, m) evaluates to true if value matches m.

13. 定义匹配

MATCHER(IsEven, "") { return (arg % 2) == 0; } Defines a matcher IsEven() to match an even number.
MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; } Defines a macher IsDivisibleBy(n) to match a number divisible by n.
MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; } Defines a matcher IsBetween(a, b) to match a value in the range [ab].

笔记:

  1. MATCHER *宏不能在函数或类中使用。
  2. 匹配器主体必须是纯功能性的(即它不能有任何副作用,并且结果必须不依赖于被匹配的值和匹配器参数之外的任何东西)。
  3. 您可以使用PrintToString(x)将任何类型的值x转换为字符串。

14. 匹配作为测试断言

ASSERT_THAT(expression, m) Generates a fatal failure if the value of expression doesn't match matcher m.
EXPECT_THAT(expression, m) Generates a non-fatal failure if the value of expression doesn't match matcher m.

六、动作Actions

操作指定了mock函数在调用时应该执行的操作。

1. 返回值

Return() Return from a void mock function.
Return(value) Return value. If the type of value is different to the mock function's return type, value is converted to the latter type at the time the expectation is set, not when the action is executed.
ReturnArg<N>() Return the N-th (0-based) argument.
ReturnNew<T>(a1, ..., ak) Return new T(a1, ..., ak); a different object is created each time.
ReturnNull() Return a null pointer.
ReturnPointee(ptr) Return the value pointed to by ptr.
ReturnRef(variable) Return a reference to variable.
ReturnRefOfCopy(value) Return a reference to a copy of value; the copy lives as long as the action.

2. 副作用(Side Effects)

Assign(&variable, value) Assign value to variable.
DeleteArg<N>() Delete the N-th (0-based) argument, which must be a pointer.
SaveArg<N>(pointer) Save the N-th (0-based) argument to *pointer.
SaveArgPointee<N>(pointer) Save the value pointed to by the N-th (0-based) argument to *pointer.
SetArgReferee<N>(value) Assign value to the variable referenced by the N-th (0-based) argument.
SetArgPointee<N>(value) Assign value to the variable pointed by the N-th (0-based) argument.
SetArgumentPointee<N>(value) Same as SetArgPointee<N>(value). Deprecated. Will be removed in v1.7.0.
SetArrayArgument<N>(first, last) Copies the elements in source range [firstlast) to the array pointed to by the N-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range.
SetErrnoAndReturn(error, value) Set errno to error and return value.
Throw(exception) Throws the given exception, which can be any copyable value. Available since v1.1.0.

3. 使用函数或函子作为动作Using a Function or a Functor as an Action

Invoke(f) Invoke f with the arguments passed to the mock function, where f can be a global/static function or a functor.
Invoke(object_pointer, &class::method) Invoke the {method on the object with the arguments passed to the mock function.
InvokeWithoutArgs(f) Invoke f, which can be a global/static function or a functor. f must take no arguments.
InvokeWithoutArgs(object_pointer, &class::method) Invoke the method on the object, which takes no arguments.
InvokeArgument<N>(arg1, arg2, ..., argk) Invoke the mock function's N-th (0-based) argument, which must be a function or a functor, with the k arguments.

被调用函数的返回值被用作动作的返回值。
定义要与Invoke *()一起使用的函数或函数时,可以将任何未使用的参数声明为未使用:

1

2

3

double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); }

  ...

EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance));

在Invoke Argument <N>(...)中,如果一个参数需要通过引用传递,则将其包装在ByRef()中。 例如,

1

InvokeArgument<2>(5, string("Hi"), ByRef(foo))

调用模拟函数#2参数,通过值传递给它5和字符串(“Hi”),并通过引用传递foo。

Default Action

Note: due to technical reasons, DoDefault() cannot be used inside a composite action - trying to do so will result in a run-time error.

Composite Actions

DoAll(a1, a2, ..., an) Do all actions a1 to an and return the result of an in each invocation. The first n - 1sub-actions must return void.
IgnoreResult(a) Perform action a and ignore its result. a must not return void.
WithArg<N>(a) Pass the N-th (0-based) argument of the mock function to action a and perform it.
WithArgs<N1, N2, ..., Nk>(a) Pass the selected (0-based) arguments of the mock function to action a and perform it.
WithoutArgs(a) Perform action a without any arguments.

Defining Actions

ACTION(Sum) { return arg0 + arg1; } Defines an action Sum() to return the sum of the mock function's argument #0 and #1.
ACTION_P(Plus, n) { return arg0 + n; } Defines an action Plus(n) to return the sum of the mock function's argument #0 and n.
ACTION_Pk(Foo, p1, ..., pk) { statements; } Defines a parameterized action Foo(p1, ..., pk) to execute the given statements.

The ACTION* macros cannot be used inside a function or class.

七、Cardinalities基数

这些在Times()中用于指定将调用模拟函数的次数:

AnyNumber() The function can be called any number of times.
AtLeast(n) The call is expected at least n times.
AtMost(n) The call is expected at most n times.
Between(m, n) The call is expected between m and n (inclusive) times.
Exactly(n) or n The call is expected exactly n times. In particular, the call should never happen when n is 0.

八、期望顺序(Expectation Order)

默认情况下,期望可以按任何顺序匹配。如果一些或所有期望必须在给定的顺序中匹配,则有两种方式来指定它们。 它们可以单独使用或一起使用。

1.The After Clause

1

2

3

4

5

6

using ::testing::Expectation;

...

Expectation init_x = EXPECT_CALL(foo, InitX());

Expectation init_y = EXPECT_CALL(foo, InitY());

EXPECT_CALL(foo, Bar())

    .After(init_x, init_y);

上边说,只有在InitX()和InitY()被调用之后才能调用Bar()。

如果你不知道你写的期望有多少个前提条件,你可以使用ExpectationSet来收集它们:

1

2

3

4

5

6

7

8

using ::testing::ExpectationSet;

...

ExpectationSet all_inits;

for (int i = 0; i < element_count; i++) {

  all_inits += EXPECT_CALL(foo, InitElement(i));

}

EXPECT_CALL(foo, Bar())

    .After(all_inits);

上面说,只有在所有元素都被初始化之后才能调用Bar()。(但我们不关心哪些元素在其他元素之前被初始化)。

在 .After(all_inits)​中使用ExpectationSet之后再修改ExpectationSet不会影响.After()的含义。

2. 序列

当你有一个长链的顺序期望,使用序列指定顺序更容易,这不需要给链中的每个期望一个不同的名称。同一序列中的所有预期调用必须按其指定的顺序发生。

1

2

3

4

5

6

7

8

9

10

11

12

using ::testing::Sequence;

Sequence s1, s2;

...

EXPECT_CALL(foo, Reset())

    .InSequence(s1, s2)

    .WillOnce(Return(true));

EXPECT_CALL(foo, GetSize())

    .InSequence(s1)

    .WillOnce(Return(1));

EXPECT_CALL(foo, Describe(A<const char*>()))

    .InSequence(s2)

    .WillOnce(Return("dummy"));

上边说,Reset()必须在GetSize()和Describe()之前调用,后两个可以以任何顺序发生。

在一个序列中方便地提出许多期望:

1

2

3

4

5

6

7

8

9

using ::testing::InSequence;

{

  InSequence dummy;

  EXPECT_CALL(...)...;

  EXPECT_CALL(...)...;

  ...

  EXPECT_CALL(...)...;

}

上边说,在dummy范围内的所有预期调用必须以严格的顺序发生。 名称dummy是不相关的。)

九、验证和重置模拟

Google Mock会在模拟对象被破坏时验证对模拟对象的期望,或者您可以更早地执行:

1

2

3

4

5

6

7

8

9

10

using ::testing::Mock;

...

// Verifies and removes the expectations on mock_obj;

// returns true iff successful.

Mock::VerifyAndClearExpectations(&mock_obj);

...

// Verifies and removes the expectations on mock_obj;

// also removes the default actions set by ON_CALL();

// returns true iff successful.

Mock::VerifyAndClear(&mock_obj);

您还可以告诉Google Mock模拟对象可以泄漏,无需进行验证:

1

Mock::AllowLeak(&mock_obj);

十、模拟类

Google Mock定义了一个方便的模拟类模板

1

2

3

4

class MockFunction<R(A1, ..., An)> {

 public:

  MOCK_METHODn(Call, R(A1, ..., An));

};

 See this recipe for one application of it.

十 一、Flags

--gmock_catch_leaked_mocks=0 Don't report leaked mock objects as failures.
--gmock_verbose=LEVEL Sets the default verbosity level (infowarning, or error) of Google Mock messages.

十二、一个关于匹配器的例子

举一个测试重载函数的匹配器的例子吧,感觉这个挺麻烦的,另外google提供了很多例子,不知道怎么写的时候,可以去里边找。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

//接口类

class Foo {

public:

   virtual bool Transform() = 0;

   // Overloaded on the types and/or numbers of arguments.

   virtual int Add(char x) = 0;

   virtual int Add(int x,int y) = 0;

   virtual int Add(int times, char x) = 0;

   

protected:

    virtual void Resume() = 0;

private:

    virtual int GetTimeOut() = 0;

};

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#include "Foo.h"

#include "gmock\gmock.h"

//模拟类

//子类修改父类的访问权限

class MockFoo : public Foo {

public:

    MOCK_METHOD0(Transform, bool());

    // The following must be in the public section, even though the

    // methods are protected or private in the base class.

    MOCK_METHOD0(Resume, void());

    MOCK_METHOD0(GetTimeOut, int());

    //virtual int Add(char x);

    //virtual int Add(int times, char x);

    // virtual int Add(int x);

    MOCK_METHOD1(Add, int(char x));

    //MOCK_METHOD1(Add, int(int x));

    MOCK_METHOD2(Add, int(int times, char x));

    // virtual int Add(int x,int y) = 0;

    MOCK_METHOD2(Add, int(int x, int y));

};

  测试用例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

#include "stdafx.h"

using namespace std;

using ::testing::Return;

using ::testing::_;

using ::testing::An;

using ::testing::Matcher;

using ::testing::Lt;

using ::testing::TypedEq;

using ::testing::Matches;

using ::testing::Le;

using ::testing::Ne;

using ::testing::AllOf;

//测试模拟private、protected方法:

TEST(TestMockPrivate, TestPrivate) {

   

    MockFoo foo;

    //GetTimeOut是private修饰的

    EXPECT_CALL(foo, GetTimeOut())

        .WillOnce(Return(1));

    cout << "test private GetTimeOut:" << foo.GetTimeOut() << endl; //1

}

//测试重载方法

TEST(TestMockOverload, TestOverload) {

    MockFoo foo;

    EXPECT_CALL(foo, Add(_))

        .Times(1)

        .WillOnce(Return(1));

    cout << "test TestOverload Add:" << foo.Add('c') << endl; //1

}

//测试数量相同,类型不同的情况。

// virtual int Add(int x,int y) = 0;

// virtual int Add(int times, char x) = 0;

TEST(TestMockOverload, TestSameNumArg) {

    MockFoo foo;

    //两个都是int

    EXPECT_CALL(foo, Add(An<int>(), An<int>()))

        .Times(1)

        .WillOnce(Return(8));

    int c = foo.Add(3, 5);

    cout << "test TestOverload Add:" <<c<< endl; //8

     

    EXPECT_CALL(foo, Add(Matcher<int>(Lt(10)), TypedEq<char>('c')))

        .Times(1)

        .WillOnce(Return(7));

    c = foo.Add(2, 'c');

    cout << "test TestOverload Add:" << c << endl; //7

}

//测试数量相同,类型不同的情况。

TEST(TestMockOverload, TestSameNumArg2) {

   MockFoo foo;

   EXPECT_CALL(foo, Add(Matcher<int>(Lt(5)), An<int>()))

        .Times(1)

        .WillOnce(Return(7));

    int c = foo.Add(2, 5);

    cout << "test TestOverload Add:" << c << endl; //7

    //第一个参数小于5,,第二个参数是'd'

    EXPECT_CALL(foo, Add(Matcher<int>(Lt(5)), Matcher<char>('d')))

        .Times(1)

        .WillOnce(Return(10));

    c = foo.Add(2, 'd'); //10

    cout << "test TestOverload Add:" << c << endl; //10

}

int main(int argc, char** argv) {

    ::testing::InitGoogleMock(&argc, argv);

    return RUN_ALL_TESTS();

}

运行结果:可以看到都成功啦

ok。。结束。。

转载请注明出处:Google C++单元测试框架GoogleTest---GMock的CheatSheet文档 - 超超boy - 博客园

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Google Mock - GoogleTest(九) 的相关文章

  • jenkins+selenium+python实现web自动化测试

    jenkins selenium可以做到对web自动化的持续集成 Jenkins的基本操作 一 新建视图及job 新建视图 新建job 可以选择构建一个自由风格的软件项目或者复制已有的item 二 准备工作 安装Jenkins插件 SSH
  • 使用Hypothesis生成测试数据

    Hypothesis是Python的一个高级测试库 它允许编写 测试用例 时参数化 然后生成使测试失败的简单易懂的测试数据 可以用更少的工作在代码中发现更多的bug 安装 pip install hypothesis 如何设计 测试数据 通
  • 接口测试之Fiddler弱网测试

    前言 目前市面上的APP功能越来越丰富 移动端测试也越显为重要 因为用户在网速慢的情况下 你的网站 软件 总能出现各种各样的问题 请不要忽略这一点 针对在不同的网络情况下 接下来 本篇要讲述的就是在通过fiddler对APP进行模拟弱网测试
  • #私密朋友圈被吐槽有bug?官方致歉!网友:尴尬了......

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 2k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • Selenium小技巧!

    Chrome DevTools 简介 Chrome DevTools 是一组直接内置在基于 Chromium 的浏览器 如 Chrome Opera 和 Microsoft Edge 中的工具 用于帮助开发人员调试和研究网站 借助 Chro
  • Linux终端常见用法总结

    熟悉Linux终端的基础用法和常见技巧可以极大提高运维及开发人员的工作效率 笔者结合自身学习实践 总结以下终端用法供同行交流学习 常 见 用 法 1 快捷键 1 1 Alt 在光标位置插入上一次执行命令的最后一个参数 1 2 Ctrl R
  • RF自动化环境安装+自动化实例解析

    RF定义 通用型的 自动测试框架 绝大部分的软件的的自动化系统都可以采用它 特点 测试数据文件 Test Data 对应一个个的测试用例 测试数据文件里面使用的功能小模块叫关键字 由测试库 Test Library Robot Framew
  • Jenkins 插件下载速度慢、安装失败了!我教你怎么解决!

    Jenkins部署完毕 如果不安装插件的话 那它就是一个光杆司令 啥事也做不了 所以首先要登陆管理员账号然后点击系统管理再点击右边的插件管理安装CI CD必要插件 但是问题来了 jenkins下载插件速度非常慢 而且经常提示下载插件失败 真
  • 软件测试|sqlalchemy relationship

    简介 SQLAlchemy是一个流行的Python ORM 对象关系映射 库 它允许我们以面向对象的方式管理数据库 在SQLAlchemy中 relationship 是一个重要的功能 用于建立表之间的关系 在本文中 我们将详细探讨 rel
  • 软件测试|web自动化测试神器playwright教程(三十八)

    简介 在我们使用selenium时 我们可以获取元素的属性 元素的文本值 以及输入框的内容等 作为比selenium更为强大的web自动化测试神器 playwright也可以实现对元素属性 文本值和输入框内容的抓取 并且实现比seleniu
  • 软件测试|Pydantic处理时间类型数据

    简介 我们之前介绍过使用 pydantic 验证数据 比如校验数据的格式等 但是在我们的日常工作中 还有一种数据是需要我们验证的 比如时间数据 时间数据不同于字符串 列表等数据 与他们的验证不一样 本文就来为大家介绍一下 pydantic
  • 软件测试|使用Python读写yaml文件,你会了吗?

    简介 YAML YAML Ain t Markup Language 是一种可读的数据序列化格式 它常用于配置文件和数据交换 Python 提供了许多库来处理 YAML 文件 在本文中 我们将探讨如何使用 PyYAML 库来读取和写入 YA
  • 软件测试|pycharm关联GitHub的详细步骤

    简介 GitHub 是全球最大的开源代码托管平台之一 而 PyCharm 是一款强大的 Python 集成开发环境 将两者结合使用 可以提高团队协作和代码管理的效率 本文将详细介绍如何在 PyCharm 中管理 GitHub 账号 包括如何
  • 软件测试|如何使用selenium处理iframe富文本输入框

    简介 在网页开发中 富文本框是常见的元素 用于输入富文本内容 如富文本编辑器或邮件编辑器 如果我们要使用Python和Selenium进行自动化测试或操作这种富文本框 可能会遇到一些挑战 本文将详细介绍如何使用Python和Selenium
  • 如何写好一个错误报告

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自
  • 软件测试中的白盒测试,这些技巧你知道吗?

    对于很多刚开始学习软件测试的小伙伴来说 如果能尽早将黑盒 白盒测试弄明白 掌握两种测试的结论和基本原理 将对自己后期的学习有较好的帮助 今天 我们就来聊聊黑盒 白盒测试的相关话题 1 黑盒测试的方法和小结 最常见黑盒测试方法包括 边界值 等
  • 甜蜜而简洁 —— 深入了解Pytest插件pytest-sugar

    在日常的软件开发中 测试是确保代码质量的关键步骤之一 然而 对于测试报告的生成和测试结果的可读性 一直以来都是开发者关注的焦点 Pytest插件 pytest sugar 以其清晰而美观的输出 为我们提供了一种愉悦的测试体验 本文将深入介绍
  • 程序员找工作难!拿到外包公司的 offer 我应该去么?

    引言 前一阵子有一个帖子引起了非常广泛的讨论 描述的就是一个公司的外包工作人员 加班的时候因为吃了公司给员工准备的零食 被公司的HR当场批评 这个帖子一发出来 让现在测试行业日益新增的外包公司备受关注 那么外包公司和非外包公司有什么样的不一
  • UI自动化测试之Jenkins配置

    背景 团队下半年的目标之一是实现自动化测试 这里要吐槽一下 之前开发的测试平台了 最初的目的是用来做接口自动化测试和性能测试 但由于各种原因 接口自动化测试那部分功能整个废弃掉了 其中和易用性有很大关系 另外 也和我们公司的接口业务也有关
  • 软件测试面试:还没有自动化测试项目经验,3个项目帮你走入软测职场!

    2024软件测试面试刷题 这个小程序 永久刷题 靠它快速找到工作了 刷题APP的天花板 CSDN博客 文章浏览阅读2 3k次 点赞85次 收藏11次 你知不知道有这么一个软件测试面试的刷题小程序 里面包含了面试常问的软件测试基础题 web自

随机推荐

  • 毕设教学:Yolo v5 (v6.1)解析(二)

    Yolo v5 v6 1 解析 二 本文对YOLOv5模型的detect py文件内容进行了详细阐述 笔者以后会定期讲解关于模型的其他的模块与相关技术 笔者也建立了一个关于目标检测的交流群 781334731 大家也可扫描底部图片加入 欢迎
  • java软件官网下载汇总——JDK,eclipse,mysql,maven,idea,Git,oracle

    说明 最近换了一台电脑 所以很多软件都要重新安装 边安装边思考我不如把所有软件的下载官网记录下来 以后就不用到处找了 直接在这篇博文里看就行了 这篇博文没有具体的下载链接 只是官网 因为如果真的不记得进了官网怎么点 那确实也应该复习一下 就
  • 学习1(Linunx操作系统_前期安装)

    1 安装虚拟机 vm12 我下载的是这个版本 vmware workstation full 12 1 0 3272444 exe 下载地址 https www xinsaisai com vmware workstation full 1
  • keep-alive源码解析及实现原理

    keep alive源码 vue 2 6 10 在src core components keep alive js中 代码分析 export default name keep alive abstract true 抽象组件 props
  • 解决Mac应用程序软件不出现在Launchpad里面的方法

    新装了几个软件 可是打开Lauchpad之后却在里面找不到 尝试重置Launchpad方式 1 分别输入终端命令即可 rm Library Application Support Dock db killall Dock
  • ASP.NET 清除模式窗口数据缓存

    使用模式窗口showModalDialog 弹出页面在asp net中经常用到 用的最多的就是点击 修改 按钮 弹出修改页面 修改成功之后 关闭修改页面 刷新父页面 目前存在的一个问题是 刷新完父页面之后 再点击修改按钮弹出修改页面 修改页
  • Java 枚举

    枚举的每一个成员变量就是枚举类型自身的一个实例 枚举的实例在编译的时候就能确定枚举类型有多少个 实例对象 每一个枚举都继承自java lang Enum类 枚举的每个成员默认都是 public static final 的 当定义一个 枚举
  • gf框架使用sqlite3数据库后交叉编译cgo适配arm64-linux

    gf框架使用sqlite3数据库后交叉编译cgo适配arm64 linux 文章目录 gf框架使用sqlite3数据库后交叉编译cgo适配arm64 linux 1 前言 2 解决方案 3 wsl Windows交叉编译cgo工程 3 1
  • 期末考试复习笔记(标红表示重要)

    目录 相关系数的比较 数据的类型 回归模型的统计检验与统计意义 参数检验 非参数检验 统计距离 量表 李克特量表 权重 聚类图分析 聚类分析简介 聚类的用途 聚类方法 两步聚类法 TwoStep Cluster 箱线图分析 中心位置的作用
  • Redis数据类型-List

    一 概述 Java中 数组 Arraylist 链表 linkedList 数组的特点 根据索引取值速度是极快的 和数据量的大小无关 数组的增删改查 效率极低 数据量越大 效率越低 链表的特点 链表的元素增删 效率极高 和数据量的大小无关
  • 超详细!Jmeter性能测试(一)

    Jmeter 性能测试 一 首先开发会给你一个接口文档 我们这边是做支付方面的 所以我们要求给下单支付接口做下压测 由于我们这边接口都是有加密参数的 所以都是直接在JAVA工程包里直接跑的 因为这次是做压测 所以我们要用上Jmeter这个工
  • VC++ OpenCV4.x二维码识别

    自OpenCV4 x开始 二维码识别已经悄然进入 再也不用看zbar脸色了 以下是官网发布的源码 include opencv2 objdetect hpp include opencv2 imgproc hpp include openc
  • Node.Js篇 NodeJs使用MongoDB

    目录 介绍 概念解析 安装 启动时注意事项 NodeJs操作Mongo 介绍 MongoDB 是一个基于分布式文件存储的数据库 由 C 语言编写 旨在为 WEB 应用提供可扩展的高性能数据存储解决方案 MongoDB 是一个介于关系数据库和
  • 酷开科技打造更好体验服务用户

    智能电视以其海量资源 智慧大屏 高清画质等特点在国内快速普及 然而 随着用户量的增加 用户群体的需求多元化 导致消费者对智能电视的应用要求越来越高 不仅希望智能电视内容丰富 最好还能拥有 多合一 的功能 好在 一些科技企业关注到市场痛点 致
  • 全连接层、卷积层、深度可分离卷积的参数量计算

    一 全连接层参数的计算 若输入大小为32 32 3的图片 第一层全连接层有500个节点 则地一层全连接网络的个参数量为 32 32 3 500 500 约为150万个参数 参数量多 导致计算速度缓慢且容易造成过拟合 于是卷积操作便横空出世
  • Taro编译微信小程序实现顶部自定义导航栏

    需求 使用taro开发微信小程序的过程中 涉及到小程序的需要自定义顶部导航栏 导航栏渐变色 微信小程序中只能够设置固定的颜色 渐变颜色以及添加其他按钮的操作就不能够通过小程序自带的api来实现 思路 配置自定义导航栏设置 获取顶部状态栏高度
  • 一个进程可以创建多少线程?

    理论上 一个进程可用虚拟空间是2G 默认情况下 线程的栈的大小是1MB 所以理论上一个进程可以创建2048个线程 当然更改编译器的设置可以创建多余2048个线程 因此 一个进程可以创建的线程数由可用虚拟空间和线程的栈的大小共同决定 只要虚拟
  • PTA Python习题 计算工资

    题目要求 编写函数pay 带两个输入参数 小时工资和上周员工工作了的小时数 函数计算并返回员工的工资 加班工资的计算方法如下 大于40小时但小于或等于60小时按平时小时薪酬的1 5倍给薪 大于60小时则按平时小时薪酬的2倍给薪 函数接口定义
  • 【恒指早盘分析】期货交易绝非你想的那么简单

    对期货而言 这个市场是绝对平等的 它不需要八面玲珑的关系 不靠权势 只凭借勤奋努力来实现梦想 实现真正的财务自由 因此 对每一位立志于靠智慧生活的人来说 期货投资是一个极好的发展领域 从平时的练习和实践中 可以得到身 心 技的全面塑造和修行
  • Google Mock - GoogleTest(九)

    本文翻译自 https github com google googletest blob master googlemock docs CheatSheet md 一 定义一个模拟类 1 模拟一个正常的类 就是接口类 给 1 2 3 4