【问题标题】:Unit Test Embedded C++ Code using Visual Studio 2010使用 Visual Studio 2010 对嵌入式 C++ 代码进行单元测试
【发布时间】:2011-07-23 00:42:10
【问题描述】:

我有要重构/添加的遗留代码。该代码是用 C++ 编写的,针对使用 Greenhills 编译器的嵌入式设备。听说 Visual Studio 2010 的测试框架更好,编写测试用例的工作量更少。是否可以使用 VS2010 对嵌入式代码进行单元测试?将不胜感激有关如何执行此操作或逐步过程的示例。

如果没有,CppUnit/CxxTest如何与VS2010集成?我找不到关于如何实现这一点的明确文档。

【问题讨论】:

  • 我建议通过使用一个小型应用程序并让 CppUnit 使用 VS2010 构建来开始开发项目。构建 CppUnit 后,添加其余代码。 CppUnit 构建后很容易扩展。

标签: c++ visual-studio-2010 embedded


【解决方案1】:

您可以在 Visual Studio 中编译嵌入式软件。为平台特定功能和 Green Hills 特定功能(如果有)创建存根。还要注意任何特定的 Green Hills 宏。您需要找到或创建等效项。

我在 Visual Studio 2008 中使用带有 wxWidgets 的 CppUnit。我没有尝试单独将 CppUnit 与 Visual Studio 2010 集成。

请记住,您希望将验证代码与嵌入代码分开。嵌入代码应作为库和头文件导入您的验证项目。这使测试保持诚实(尽管我意识到您可能无法将 Green Hills 库与 Visual Studio 库链接)。否则使用 VS 构建嵌入式代码,但在构建步骤中作为单独的库。

如果可能,围绕软件需求设计您的测试。之后,设计一些代码来执行公共功能。请记住,开发人员不应该编写代码来满足测试,测试人员也不应该编写代码来满足开发人员的功能。 “如果它存在,请测试它。”或“如果使用,请测试它”。例如,平台可能有一个 DMA 控制器但不使用它。

编辑 #1 -- 示例

给定“嵌入式”或实现中的以下类:

class Title
{
  public:
                                    Title();
                                    Title(const Title& rc);
    virtual                         ~Title();
    Title&                          operator= (const Title& rt);
    const std::string&              get_table_name(void) const;
    const std::string&              get_title_text(void) const;
    void                            set_table_name(const std::string&);
    void                            set_title_text(const std::string& new_text);
};

CppUnit 测试类如下所示:

#include "cppunit/extensions/HelperMacros.h"

class Test_Ing_Title
    : public CPPUNIT_NS::TestFixture
{
    //---------------------------------------------------------------------
    //  Friends
    //---------------------------------------------------------------------
    CPPUNIT_TEST_SUITE(Test_Ing_Title);
    CPPUNIT_TEST(ing_name_field_testing);
    CPPUNIT_TEST(copying);
    CPPUNIT_TEST(table_name_testing);
    CPPUNIT_TEST(test_id_field);
    CPPUNIT_TEST(title_testing);
    CPPUNIT_TEST(visitor_test);
    CPPUNIT_TEST_SUITE_END();

    //---------------------------------------------------------------------
    //  Public types
    //---------------------------------------------------------------------
  public:

    //---------------------------------------------------------------------
    //  Public Constructors and Destructors
    //---------------------------------------------------------------------
  public:
    //! Constructor - Default
                                Test_Ing_Title();

    //! Copy Constructor
                                Test_Ing_Title(const Test_Ing_Title& n_obj);

    //! Destructor
    virtual                     ~Test_Ing_Title();

    //---------------------------------------------------------------------
    //  Public Overloaded Operators
    //---------------------------------------------------------------------
  public:

    //---------------------------------------------------------------------
    //  Public Methods
    //---------------------------------------------------------------------
  public:
    //! Test cloning of the title record.
    void                        cloning(void);

    //! Test copying
    void                        copying(void);

    //! Test the name field getters and setters
    void                        ing_name_field_testing(void);

    //! Test the table name getters & setters
    void                        table_name_testing(void);

    void                        tearDown(void);

    //! Test the ID field getters and setters.
    void                        test_id_field(void);

    //! Test the title getters and setters
    void                        title_testing(void);

    //! Test visitors to the title.
    void                        visitor_test(void);
};

一个示例测试方法:

#include <stdafx.h>     // This line is required for precompiled headers on MSVC++.
#include <cppunit/TestCase.h>
#include <cppunit/extensions/HelperMacros.h>
#include <string>

void
Test_Ing_Title ::
title_testing(void)
{
    static const char           expected_title_text[] = "Ground Beef";
    const std::string           expected_title(expected_title_text);
    std::string             actual_title;
    Ingredient::Records::Title  ing_title;
    ing_title.set_title_text(expected_title);
    actual_title = ing_title.get_title_text();
    CPPUNIT_ASSERT(actual_title == expected_title);
    return;
}

在上面的例子中,测试类创建了一个要测试的类的实例,然后执行这些方法。关键是测试类与系统隔离,或者换句话说,测试类不影响被测系统。将测试代码放在单独的位置将有助于强调这一概念。将“嵌入式”代码视为只读。测试到极致,坚守阵地,减少的产品退货数量将成为您的回报(并增加公司的利润)。

HTH。

【讨论】:

  • Thomas,非常感谢您的详细回答。还有一件事,即使我有单个类的源代码,我也必须构建一个库,然后使用 CppUnit 对其进行测试?我希望我可以在 VS 中添加测试类来测试我的 C++ 实现(只有一个类和依赖项)。你能提供一个好的入门教程吗?谢谢。
  • @Rob,看我的Edit #1。我还没有找到一个好的入门教程。我的工作量很大。阅读所有 CppUnit 文档并在网上搜索示例。
  • 非常感谢您在编辑 #1 中的出色清晰度,非常有帮助。我将在我的代码上进行尝试并发布反馈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
  • 2015-05-03
  • 1970-01-01
相关资源
最近更新 更多