unit-testing ट्यूटोरियल
यूनिट-टेस्टिंग के साथ शुरुआत करना
खोज…
टिप्पणियों
यूनिट टेस्टिंग उस प्रणाली से अलगाव में कोड की अलग-अलग इकाइयों के परीक्षण की प्रक्रिया का वर्णन करता है जो वे का एक हिस्सा हैं। एक इकाई का गठन सिस्टम से सिस्टम में अलग-अलग हो सकता है, जिसमें व्यक्तिगत विधि से लेकर निकट से संबंधित वर्गों या मॉड्यूल तक का समूह हो सकता है।
यूनिट आवश्यक होने पर परीक्षण डबल्स का उपयोग करके अपनी निर्भरता से अलग हो जाता है और एक ज्ञात स्थिति में सेट हो जाता है। उत्तेजनाओं की प्रतिक्रिया में इसका व्यवहार (विधि कॉल, ईवेंट, सिम्युलेटेड डेटा) तब अपेक्षित व्यवहार के खिलाफ परीक्षण किया जाता है।
पूरे सिस्टम का यूनिट परीक्षण कस्टम लिखित टेस्ट हार्नेस का उपयोग करके किया जा सकता है, हालांकि प्रक्रिया को सुव्यवस्थित करने और प्लंबिंग, दोहराव और सांसारिक कार्यों की अधिक देखभाल करने में मदद करने के लिए कई टेस्ट फ्रेमवर्क लिखे गए हैं। यह डेवलपर्स को इस बात पर ध्यान केंद्रित करने की अनुमति देता है कि वे क्या परीक्षण करना चाहते हैं।
जब किसी प्रोजेक्ट में पर्याप्त इकाई होती है, तो नई कार्यक्षमता जोड़ने या कोड रीफैक्टरिंग करने के किसी भी संशोधन का परीक्षण आसानी से अंत में सत्यापित करके किया जा सकता है कि सब कुछ पहले की तरह काम करता है।
कोड कवरेज , जिसे आम तौर पर प्रतिशत के रूप में व्यक्त किया जाता है, एक विशिष्ट मीट्रिक है जिसे यह दिखाने के लिए उपयोग किया जाता है कि सिस्टम में कितना कोड यूनिट टेस्ट द्वारा कवर किया गया है; ध्यान दें कि यह कितना उच्च होना चाहिए, इसके बारे में कोई कठिन और तेज़ नियम नहीं है, लेकिन आमतौर पर यह स्वीकार किया जाता है कि उच्च, बेहतर।
टेस्ट ड्रिवेन डेवलपमेंट (टीडीडी) एक सिद्धांत है जो यह निर्दिष्ट करता है कि एक डेवलपर को फेलिंग यूनिट टेस्ट लिखकर कोडिंग शुरू करनी चाहिए और उसके बाद ही उत्पादन कोड लिखने के लिए टेस्ट पास करना चाहिए। टीडीडी का अभ्यास करते समय, यह कहा जा सकता है कि परीक्षण स्वयं ही बनाए जा रहे कोड के पहले उपभोक्ता हैं; इसलिए वे कोड के डिजाइन को ऑडिट करने और चलाने में मदद करते हैं ताकि यह उपयोग करना जितना आसान हो और जितना संभव हो उतना मजबूत हो।
संस्करण
यूनिट परीक्षण एक अवधारणा है जिसमें संस्करण संख्याएं नहीं हैं।
एक बुनियादी इकाई परीक्षण
इसके सरलतम में, एक इकाई परीक्षण में तीन चरण होते हैं:
- परीक्षण के लिए वातावरण तैयार करें
- परीक्षण किए जाने वाले कोड को निष्पादित करें
- अपेक्षित व्यवहार को मान्य व्यवहार से मेल खाता है
इन तीन चरणों को अक्सर 'अरेंज-एक्ट-एस्टर', या 'गिवेन-व्हेन-तब' कहा जाता है।
नीचे C # में उदाहरण है जो NUnit ढांचे का उपयोग करता है।
[TestFixture]
public CalculatorTest
{
[Test]
public void Add_PassSevenAndThree_ExpectTen()
{
// Arrange - setup environment
var systemUnderTest = new Calculator();
// Act - Call system under test
var calculatedSum = systemUnderTest.Add(7, 3);
// Assert - Validate expected result
Assert.AreEqual(10, calculatedSum);
}
}
जहां आवश्यक हो, एक वैकल्पिक चौथा क्लीन अप स्टेज टिडिज अप।
स्टब्ड निर्भरता के साथ एक इकाई परीक्षण
अच्छी इकाई परीक्षण स्वतंत्र होते हैं, लेकिन कोड में अक्सर निर्भरता होती है। हम परीक्षण के लिए निर्भरता को दूर करने के लिए विभिन्न प्रकार के परीक्षण डबल्स का उपयोग करते हैं। सबसे सरल टेस्ट डबल्स में से एक स्टब है। यह एक वास्तविक-विश्व निर्भरता के स्थान पर हार्ड-कोडेड रिटर्न वैल्यू के साथ एक फ़ंक्शन है।
// Test that oneDayFromNow returns a value 24*60*60 seconds later than current time
let systemUnderTest = new FortuneTeller() // Arrange - setup environment
systemUnderTest.setNow(() => {return 10000}) // inject a stub which will
// return 10000 as the result
let actual = systemUnderTest.oneDayFromNow() // Act - Call system under test
assert.equals(actual, 10000 + 24 * 60 * 60) // Assert - Validate expected result
उत्पादन कोड में, oneDayFromNow
Date.now () को कॉल करेगा, लेकिन यह असंगत और अविश्वसनीय परीक्षणों के लिए होगा। तो यहां हम इसे बाहर निकालते हैं।
एक जासूस के साथ एक इकाई परीक्षण (इंटरैक्शन टेस्ट)
क्लासिक यूनिट परीक्षण स्थिति का परीक्षण करती है , लेकिन उन तरीकों को ठीक से जांचना असंभव हो सकता है जिनका व्यवहार राज्य के माध्यम से अन्य वर्गों पर निर्भर करता है। हम इन तरीकों का इंटरेक्शन टेस्ट के माध्यम से परीक्षण करते हैं , जो यह सत्यापित करते हैं कि परीक्षण के तहत सिस्टम अपने सहयोगियों को सही ढंग से कहता है। चूंकि सहयोगियों के पास अपनी इकाई परीक्षण हैं, यह पर्याप्त है, और वास्तव में परीक्षण पद्धति की वास्तविक जिम्मेदारी का बेहतर परीक्षण है। हम परीक्षण नहीं करते हैं कि यह विधि किसी विशेष परिणाम को इनपुट के रूप में लौटाती है, बल्कि इसके बजाय कि यह अपने सहयोगी (ओं) को सही ढंग से बुलाती है।
// Test that squareOfDouble invokes square() with the doubled value
let systemUnderTest = new Calculator() // Arrange - setup environment
let square = spy()
systemUnderTest.setSquare(square) // inject a spy
let actual = systemUnderTest.squareOfDouble(3) // Act - Call system under test
assert(square.calledWith(6)) // Assert - Validate expected interaction
सरल जावा + JUnit टेस्ट
JUnit जावा कोड के परीक्षण के लिए इस्तेमाल किया जाने वाला अग्रणी परीक्षण ढांचा है।
टेस्ट मॉडल के अंतर्गत आने वाला वर्ग एक साधारण बैंक खाता है, जब आप ओवरड्राॅन जाते हैं तो जुर्माना वसूलते हैं।
public class BankAccount {
private int balance;
public BankAccount(int i){
balance = i;
}
public BankAccount(){
balance = 0;
}
public int getBalance(){
return balance;
}
public void deposit(int i){
balance += i;
}
public void withdraw(int i){
balance -= i;
if (balance < 0){
balance -= 10; // penalty if overdrawn
}
}
}
यह परीक्षण वर्ग BankAccount
सार्वजनिक विधियों में से कुछ के व्यवहार को मान्य करता है।
import org.junit.Test;
import static org.junit.Assert.*;
// Class that tests
public class BankAccountTest{
BankAccount acc;
@Before // This will run **before** EACH @Test
public void setUptestDepositUpdatesBalance(){
acc = new BankAccount(100);
}
@After // This Will run **after** EACH @Test
public void tearDown(){
// clean up code
}
@Test
public void testDeposit(){
// no need to instantiate a new BankAccount(), @Before does it for us
acc.deposit(100);
assertEquals(acc.getBalance(),200);
}
@Test
public void testWithdrawUpdatesBalance(){
acc.withdraw(30);
assertEquals(acc.getBalance(),70); // pass
}
@Test
public void testWithdrawAppliesPenaltyWhenOverdrawn(){
acc.withdraw(120);
assertEquals(acc.getBalance(),-30);
}
}
NUnit और C # का उपयोग करने वाले पैरामीटर के साथ यूनिट टेस्ट
using NUnit.Framework;
namespace MyModuleTests
{
[TestFixture]
public class MyClassTests
{
[TestCase(1, "Hello", true)]
[TestCase(2, "bye", false)]
public void MyMethod_WhenCalledWithParameters_ReturnsExpected(int param1, string param2, bool expected)
{
//Arrange
var foo = new MyClass(param1);
//Act
var result = foo.MyMethod(param2);
//Assert
Assert.AreEqual(expected, result);
}
}
}
एक बुनियादी अजगर इकाई परीक्षण
import unittest
def addition(*args):
""" add two or more summands and return the sum """
if len(args) < 2:
raise ValueError, 'at least two summands are needed'
for ii in args:
if not isinstance(ii, (int, long, float, complex )):
raise TypeError
# use build in function to do the job
return sum(args)
अब परीक्षण भाग:
class Test_SystemUnderTest(unittest.TestCase):
def test_addition(self):
"""test addition function"""
# use only one summand - raise an error
with self.assertRaisesRegexp(ValueError, 'at least two summands'):
addition(1)
# use None - raise an error
with self.assertRaises(TypeError):
addition(1, None)
# use ints and floats
self.assertEqual(addition(1, 1.), 2)
# use complex numbers
self.assertEqual(addition(1, 1., 1+2j), 3+2j)
if __name__ == '__main__':
unittest.main()
मापदंडों के साथ एक XUnit परीक्षण
using Xunit;
public class SimpleCalculatorTests
{
[Theory]
[InlineData(0, 0, 0, true)]
[InlineData(1, 1, 2, true)]
[InlineData(1, 1, 3, false)]
public void Add_PassMultipleParameters_VerifyExpected(
int inputX, int inputY, int expected, bool isExpectedCorrect)
{
// Arrange
var sut = new SimpleCalculator();
// Act
var actual = sut.Add(inputX, inputY);
// Assert
if (isExpectedCorrect)
{
Assert.Equal(expected, actual);
}
else
{
Assert.NotEqual(expected, actual);
}
}
}
public class SimpleCalculator
{
public int Add(int x, int y)
{
return x + y;
}
}