CppUnit TDD之探索swf文件头(上)

序言:
1.用TDD的思想去了解未知的领域
2.既然都是要写一些测试程序,为什么不让这些测试程序可以保存下来以备不时之需
3.能确保我们写过的东西,不会再出错。(曾几何时,发现自己本来写好的软件。BUG不是已经改了吗?原来是改另一个BUG改出来的,有了TDD,这种问题至少会少很多。)
CPPUNIT一大缺点之一就是没有快速的测试框架生成工具。就像VC不如C++BUILDER招人喜欢一样。不是RAD工具,自然就增加了使用门槛。
言归正传,写代码就是要做好足够准备。
如果你安装完我制作的安装包,CPPUNIT还不能用,
自己制作了一个安装包,但是上传几十次都失败。看来注定不让我上传。谁要,或者提供空间,留言吧。该安装包支持的环境vs2005,带的cppunit为0.1.12
绿色安装包,不含任何流氓代码。请大家放心使用。如果大家都已经配置好环境了,那就开始写代码喽。
其实文件格式都是差不多的。swf也一样。
The Macromedia Flash (SWF) Header
All Macromedia Flash (SWF) files begin with the following header:
SWF File Header
Field
Type*
Comment
Signature
UI8
Signature byte always ‘F’
Signature
UI8
Signature byte always ‘W’
Signature
UI8
Signature byte always ‘S’
Version
UI8
Single byte file version (e.g. 0x04F for SWF 4)
FileLength
Length of entire file in bytes
FrameSize
Frame size in twips
FrameRate
Frame delay in 8.8 fixed number of frames per second
FrameCount
Total number of frames in movie
* The types used in this header are defined in the Basic Types section.
The header beings with the three-byte Signature 0x46,0x57,0x53 (“FWS”) followed by a one-byte Version number. The version number is not an ASCII character,but an 8-bit number. For example,for SWF 4 the version byte is 0x04,not the ASCII character ‘4’ (0x35).
The FileLength field is the total length of the SWF file including the header. The FrameSize field defines the width and height of the movie. This is stored as a RECT structure.
Note: The RECT structure used for FrameSize always has the Nbits field set to 15.
The FrameRate is the desired playback rate in frames per second. This rate is not guaranteed if the SWF file contains streaming sound data,or the player is running on a slow cpu. The FrameCount is the total number of frames in this SWF movie.
UI8相当于 BYTE
UI16相当于WORD
UI32相当于DWORD
RECT在这个格式里面有点特殊
Using Bit Values
Whenever possible,bit values are packed into the smallest possible number of bits possible. Coordinates are commonly stored using variable-sized bit fields. A field indicates how many bits are used to represent subsequent values in the record. For example,take a look at the RECT structure below:
RECT
Field
Type
Comment
Nbits
nBits = UB[5]
Bits in each rect value field
Xmin
SB[nBits]
X minimum position for rect
Xmax
SB[nBits]
X maximum position for rect
Ymin
SB[nBits]
Y minimum position for rect
Ymax
SB[nBits]
Y maximum position for rect
The nBits field determines the number of bits used to store the coordinate values Xmin,Xmax,Ymin,and Ymax. Say the coordinates of the rectangle were as follows:
Xmin = 127 decimal = 1111111 binary
Xmax = 260 decimal = 10000100 binary
Ymin = 15 decimal = 1111 binary
Ymax = 514 decimal = 1000000010 binary
Nbits is calculated by finding the coordinate that requires the most bits to represent. In this case that value is 514 (01000000010 binary) which requires 11 bits to represent. So the rectangle is stored as below:
RECT
Field
Type
Comment
Nbits
UB[5] = 1011
Bits required (11)
Xmin
SB[11] = 00001111111
X minimum in twips (127)
Xmax
SB[11] = 00010000100
X maximum in twips (260)
Ymin
SB[11] = 00000001111
Y minimum in twips (15)
Ymax
SB[11] = 01000000010
Y maximum in twips (514)
看明白了吗?我也有点儿晕。还没吃饭呢。
不看了,写个大概,慢慢调试吧。
找了个相关教程,读取SWF格式的, http://www.codeproject.com/KB/graphics/ReaderSWFHeader.aspx
代码是C#的。凑合看吧。照着用吧。
开始配置环境喽。
要使用 CppUnit ,还得设置好头文件和库文件路径,以 VC6 为例,选择 Tools/Options/Directories ,在 Include files Library files 中分别添加 %CppUnitPath%/include % 这两个大家都会吧。指定绝对路径也没有问题。安装程序还没有这个功能 :(
个人不喜欢每次都写在.h和.cpp里面写头文件支持unicode和mbcs,所以,基本能放到stdafx里面的,我都会放到那里。
  • 1.stdafx.h里面引用#include "cppunitwrapper.h"就行了。
cppunitwrapper.h如下;
#pragma once
// usage : BOOL CMFCTApp::InitInstance() add list down
//#include "RobottestCase.h"
//CppUnit::MfcUi::TestRunner runner;
//runner.addTest(CRobottestCase::GetSuite());
//runner.run();
//return TRUE;
//#include "cppunit/TestCase.h"
#include <CppUnit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/mfc/TestRunner.h>
// Version number of package
#include <cppunit/Portability.h>
//#ifndef CPPUNIT_VERSION
//#define CPPUNIT_VERSION"1.12.0"
//#endif
#if _DEBUG && _UNICODE
#pragma comment(lib,"cppunitd")
#pragma comment(lib,"testrunnerud")
#elif _DEBUG && _MBCS
#pragma comment(lib,"testrunnerd")
#elif _UNICODE
#pragma comment(lib,"cppunit")
#pragma comment(lib,"testrunneru")
#else
#pragma comment(lib,"testrunner")
#endif
  • 2拷贝测试模板程序,没有RAD框架生成,只能拷贝了。
//SwfReaderTest.h
#pragma once
//#include "../mfc/Demo.h" // 被测试类
//#include "swfreader.h"
class CSwfReaderTest : public CppUnit::TestCase
{
// 宏定义
CPPUNIT_TEST_SUITE(CSwfReaderTest); // 开始声明一个新的测试程序集
CPPUNIT_TEST(TestAdd); // 添加TestAdd测试函数到测试程序集
CPPUNIT_TEST(TestSubtration); // 添加TestSubtration测试函数到测试程序集
CPPUNIT_TEST_SUITE_END(); // 声明结束
public:
CSwfReaderTest(void);
~CSwfReaderTest(void);
//static CppUnit::Test* GetSuite();
static std::string GetSuiteName() { return "CSwfReaderTest";}
void TestAdd();
void TestSubtration();
};
//SwfReaderTest.cpp
#include "StdAfx.h"
#include "SwfReaderTest.h"
// 对指定程序集进行注册
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CSwfReaderTest,CSwfReaderTest::GetSuiteName());
// 注册到指定组
CPPUNIT_REGISTRY_ADD_TO_DEFAULT(CSwfReaderTest::GetSuiteName());
CSwfReaderTest::CSwfReaderTest(void)
{
}
CSwfReaderTest::~CSwfReaderTest(void)
{
}
void CSwfReaderTest::TestAdd()
{
//CDemo cDemo;
//int iResult = cDemo.Add(10);
int iResult = 11;
// 宏判断两个值是否相等
CPPUNIT_ASSERT_EQUAL(iResult,11);
}
void CSwfReaderTest::TestSubtration()
{
//CDemo cDemo;
//int iResult = cDemo.Subtration(10);
int iResult = -10;
// 宏判断两个值是否相等
CPPUNIT_ASSERT_EQUAL(iResult,-10);
}
工程使用_MBSC编译,有个函数在unicode下有点儿问题。尚没找到方法
行了。运行程序看到绿色的运行提示吗?(为什么不是蓝色的?)
先写到这里。先把TDD环境配置好。对目标有个了解,然后开始着手去做。
参考文献:
《重构》
《TDD测试驱动开发》
CPPUNIT相关文档以及cookbook

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...