यहां एक उदाहरण दिया गया है कि आप किसी दिए गए फ़ंक्शन के लिए एक परीक्षण प्रोग्राम में एकाधिक परीक्षण कैसे कार्यान्वित करेंगे जो लाइब्रेरी फ़ंक्शन को कॉल कर सकता है।
#include <stdlib.h>
int my_div(int x, int y)
{
if (y==0) exit(2);
return x/y;
}
हम उसके बाद निम्न परीक्षण कार्यक्रम बनाने के लिए::
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <setjmp.h>
// redefine assert to set a boolean flag
#ifdef assert
#undef assert
#endif
#define assert(x) (rslt = rslt && (x))
// the function to test
int my_div(int x, int y);
// main result return code used by redefined assert
static int rslt;
// variables controling stub functions
static int expected_code;
static int should_exit;
static jmp_buf jump_env;
// test suite main variables
static int done;
static int num_tests;
static int tests_passed;
// utility function
void TestStart(char *name)
{
num_tests++;
rslt = 1;
printf("-- Testing %s ... ",name);
}
// utility function
void TestEnd()
{
if (rslt) tests_passed++;
printf("%s\n", rslt ? "success" : "fail");
}
// stub function
void exit(int code)
{
if (!done)
{
assert(should_exit==1);
assert(expected_code==code);
longjmp(jump_env, 1);
}
else
{
_exit(code);
}
}
// test case
void test_normal()
{
int jmp_rval;
int r;
TestStart("test_normal");
should_exit = 0;
if (!(jmp_rval=setjmp(jump_env)))
{
r = my_div(12,3);
}
assert(jmp_rval==0);
assert(r==4);
TestEnd();
}
// test case
void test_div0()
{
int jmp_rval;
int r;
TestStart("test_div0");
should_exit = 1;
expected_code = 2;
if (!(jmp_rval=setjmp(jump_env)))
{
r = my_div(2,0);
}
assert(jmp_rval==1);
TestEnd();
}
int main()
{
num_tests = 0;
tests_passed = 0;
done = 0;
test_normal();
test_div0();
printf("Total tests passed: %d\n", tests_passed);
done = 1;
return !(tests_passed == num_tests);
}
assert
को पुनर्परिभाषित एक बूलियन चर अद्यतन करने के लिए रखकर आप पर अगर एक जारी रख सकते हैं
मान लीजिए हम निम्नलिखित मॉड्यूल का परीक्षण करना चाहते दावा कितना सफल हुआ और कितने असफल रहा, इसका ट्रैक रखते हुए, कई परीक्षणों में विफल रहता है और चलाता है।
प्रत्येक परीक्षण की शुरुआत में, rslt
(मैक्रो द्वारा उपयोग किए जाने वाले चर) को 1 पर सेट करें, और अपने स्टब फ़ंक्शंस को नियंत्रित करने वाले किसी भी चर सेट करें।यदि आपके स्टब्स में से एक बार एक से अधिक बार बुलाया जाता है, तो आप नियंत्रण चर के सरणी सेट कर सकते हैं ताकि स्टब्स विभिन्न कॉलों पर विभिन्न स्थितियों की जांच कर सकें।
चूंकि कई लाइब्रेरी फ़ंक्शन कमजोर प्रतीक हैं, इसलिए उन्हें आपके परीक्षण कार्यक्रम में फिर से परिभाषित किया जा सकता है ताकि उन्हें इसके बजाय बुलाया जा सके। फ़ंक्शन को परीक्षण करने के लिए कॉल करने से पहले, आप स्टब फ़ंक्शन के व्यवहार को नियंत्रित करने और फ़ंक्शन पैरामीटर पर स्थितियों की जांच करने के लिए कई राज्य चर सेट कर सकते हैं।
ऐसे मामलों में जहां आप इसे फिर से परिभाषित नहीं कर सकते हैं, स्टब फ़ंक्शन को एक अलग नाम दें और परीक्षण के लिए कोड में प्रतीक को दोबारा परिभाषित करें। उदाहरण के लिए, यदि आप fopen
स्टब करना चाहते हैं लेकिन पाते हैं कि यह एक कमजोर प्रतीक नहीं है, तो अपने स्टब को my_fopen
के रूप में परिभाषित करें और फ़ाइल को -Dfopen=my_fopen
के साथ परीक्षण करने के लिए संकलित करें।
इस विशेष मामले में, परीक्षण करने के लिए फ़ंक्शन exit
पर कॉल कर सकता है। यह मुश्किल है, क्योंकि exit
परीक्षण किए जा रहे फ़ंक्शन पर वापस नहीं आ सकता है। यह दुर्लभ समय में से एक है जब setjmp
और longjmp
का उपयोग करना समझ में आता है। फ़ंक्शन में फ़ंक्शन दर्ज करने से पहले setjmp
का उपयोग करें, फिर exit
पर स्टब किए गए आप longjmp
पर सीधे अपने परीक्षण मामले पर वापस लौटने के लिए कॉल करें।
यह भी ध्यान रखें कि पुन: परिभाषित exit
में एक विशेष चर है कि यह देखने के लिए जांचता है कि क्या आप वास्तव में प्रोग्राम से बाहर निकलना चाहते हैं और ऐसा करने के लिए _exit
पर कॉल करें। यदि आप ऐसा नहीं करते हैं, तो आपका परीक्षण प्रोग्राम साफ़ रूप से नहीं छोड़ा जा सकता है।
यह परीक्षण सूट भी प्रयास किए गए और असफल परीक्षणों की संख्या की गणना करता है और यदि सभी परीक्षण पास हुए और 1 अन्यथा 0 लौटाता है। इस तरह, make
परीक्षण विफलताओं की जांच कर सकते हैं और तदनुसार कार्य कर सकते हैं।
ऊपर परीक्षण कोड इच्छा उत्पादन निम्नलिखित:
-- Testing test_normal ... success
-- Testing test_div0 ... success
Total tests passed: 2
और वापसी कोड 0.
नहीं हैं। आप यह भी दिखाते हैं कि सी में निर्भरता इंजेक्शन की व्यावहारिक आवश्यकता को कैसे संभालना है, जो वास्तविक इकाई-परीक्षण प्राप्त करने के लिए कोड-पहुंच को अलग करने की प्राथमिक तकनीक है। – kirakun