我正在对C代码进行功能测试。到目前为止,在测试.cpp文件中已包含.c文件,一切正常。但是我需要在另一个进行其他单元测试的.cpp文件中包含相同的.c文件。然后我得到已经定义的问题。因为我已经将它包含在第一个文件cpp中。
如果将所有测试方法合并到一个cpp文件中,则它将很好地工作。如果将所有单元测试都放在一个文件中,那么我需要在同一项目中拆分不同的文件,它还会创建帮助函数以确保将函数放入胶囊中。
这不是正常的LNK2005,因为我无法在.h中声明变量和函数:extern BOOL MyBool;。然后将其分配给.c或.cpp文件。因为我需要对c文件进行单元测试才能使用此功能。我也不能或应该避免进行任何更改。c。
我正在寻找保留.c local的方法,而不会影响同一项目中的其他文件。
source.h
#ifndef SOURCE_H_
#define SOURCE_H_
#include "../car.h"
enum INITIALMODE {
INITIALMODE_NOT_POSITIONING, // 0
INITIALMODE_NO_DRIVER_INPUT, // 1
INITIALMODE_POSITION_LOW_POSITION, // 2
INITIALMODE_POSITION_STANDARD_POSITION, // 3
INITIALMODE_POSITION_HIGH_POSITION // 4
};
void initMotor(void);
#endif
source.c
/* Compiler include files */
#pragma once
#include "positioning.h"
#include "api.h"
#include "drive.h"
#include "types.h"
static void updateTarget(void);
static SWord getMax(UWord Limit, UWord Aux);
static DWord getHeight(void);
static Bool isMode(void);
static Bool isExiting(void);
#define cMaxHeight 100 * Profile.s.Max /* m -> mm */
void initMotor(void)
{
// do something
}
static void updatePositioning(void)
{
// do something
}
测试文件看起来像这样,但是,它的规模非常小,可以缩小示例范围。
UnitTest.cpp 和 UnitTest2.cpp
#include "CppUnitTest.h"
#ifndef UNIT_TEST
#define UNIT_TEST
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace Test
{
extern "C" {
#include "../../Test/source.h"
#include "../../Test/source.c"
}
TEST_CLASS(UnitTest_1)
{
public:
TEST_METHOD(Test_1)
{
// Verify that the initial state is as expected.
initTest();
//Expected value
UWord Expected = 500
//Trigger to execute.
UWord Test = updatePositioning();
// Verify that the results are as expected.
Assert::AreEqual(Expected, Test);
}
};
}
#endif
答案 0 :(得分:1)
您永远不应包含.C或.CPP文件。
但是,您可以用C ++编译C代码。这是一个基于您在初始帖子中提供的信息的示例。
YourCCode.h
#ifndef YourCCode_H
#define YourCCode_H
int FunctionToTest(int SomeParams);
int TestStaticFunctions(int SomeParam1, int SomeParam2);
#endif // YourCCode_H
YourCCode.c
#include "YourCCode.h"
static int SomeStaticFunction(int Param1, int Param2)
{
return Param1 + Param2; // that needs extensive testing, obviously.
}
int FunctionToTest(int SomeParams)
{
return SomeStaticFunction(SomeParams, 1);
}
int TestStaticFunctions(int SomeParam1, int SomeParam2)
{
return SomeStaticFunction(SomeParam1, SomeParam2);
}
UnitTest1.cpp
extern "C" {
#include "YourCCode.h"
}
bool TestFunction(int Value)
{
return (FunctionToTest(Value) == Value+1);
}
UnitTest2.cpp
extern "C" {
#include "YourCCode.h"
}
void AnotherTestFunction(int Val, int Val2)
{
int newValue = TestStaticFunctions(Val, Val2);
ASSERT(newValue == Val+Val2);
}
然后编译您的CPP和C文件。
在澄清了意图之后,我意识到您正在尝试从另一个单元测试静态函数。根据定义,静态功能仅可用于同一翻译单元中的其他功能。这主要是用于防止程序员在不知道如何验证其输入,不知道调用顺序等情况下调用某些函数的保护措施。
在这里,我最好的选择是要么选择功能不是静态的,然后就可以在翻译单元外部对其进行测试,要么在包含这些静态函数的翻译单元内部实现测试功能。我建议后者,因为翻译部门应该(从体系结构上来说)知道如何测试自己的功能。
作为第三种解决方案,如果您对C文件的内容没有任何控制权(但是由于您拥有C文件,我对此表示怀疑),则可以使用包含C文件的代理CPP文件,并为每个静态呼叫创建一个代理呼叫。
但是,这是一个丑陋的破解,如果C文件得到更新,很可能会很容易破解,所以我建议不要这样做。
这是一个简单的例子:
YourCCode.h
#ifndef YourCCode_H
#define YourCCode_H
void SomeFunction(void);
#endif // YourCCode_H
YourCCode.c
#include "YourCCode.h"
static int AddSomething(int Param1, int Param2)
{
return Param1 + Param2;
}
static int SubtractSomething(int Param1, int Param2)
{
return Param1 - Param2;
}
void SomeFunction(void)
{
// code meant to be called externally.
}
ProxyTestCode.hpp
bool TestAddSomething(void);
bool TestSubtractSomething(void);
ProxyTestCode.cpp
extern "C" {
#include "YourCCode.h"
#include "YourCCode.c"
}
bool TestAddSomething(void)
{
return (AddSomething(2,2) == 4);
}
bool TestSubtractSomething(void)
{
return (AddSomething(2,2) == 0);
}
UnitTest1.cpp
#include "ProxyTestCode.hpp"
void TestAdd(void)
{
ASSERT(TestAddSomething());
}
UnitTest2.cpp
#include "ProxyTestCode.hpp"
void TestSubtract(void)
{
ASSERT(TestSubtractSomething());
}
如果这样做,不要在项目中编译C文件。