I have never written unit tests before, for various reasons. I have a chance to write tests now, conveniently, because I have a small application to do from scratch.
However, I am a little puzzled. It is assumed that the application uses a printer with a smart card reader to program data on a smart card. Thus, the sequence of actions: create the device context, set the printer mode, initialize the document, insert the card into the printer, connect to the card using a reader, write something to the card, display the card, complete the document, and utilize the device context.
Well, unit tests should test one function for each test, and each test should run independently of the result of other tests. But let's see - I can not check the recording on the smart card if I did not correctly place it in the printer, and if I did not connect to it. And I can not scoff at this software - I can only check if the spelling really happened if the real card is correctly installed and connected. And if the connection to the card fails, there is no way to check the recording on the card - so the principle of test independence is violated.
So far I have come up with such a test (there are other tests that are "correct" and check other things)
[Test] public void _WriteToSmartCard() { //start print job printer = new DataCardPrinter(); reader = new SCMSmartCardReader(); di = DataCardPrinter.InitializeDI(); printer.CreateHDC(); Assert.AreNotEqual(printer.Hdc, 0, "Creating HDC Failed"); Assert.Greater(di.cbSize, 0); int res = ICE_API.SetInteractiveMode(printer.Hdc, true); Assert.Greater(res, 0, "Interactive Mode Failed"); res = ICE_API.StartDoc(printer.Hdc, ref di); Assert.Greater(res, 0, "Start Document Failed"); res = ICE_API.StartPage(printer.Hdc); Assert.Greater(res, 0, "Start Page Failed"); res = ICE_API.RotateCardSide(printer.Hdc, 1); Assert.Greater(res, 0, "RotateCardSide Failed"); res = ICE_API.FeedCard(printer.Hdc, ICE_API.ICE_SMARTCARD_FRONT + ICE_API.ICE_GRAPHICS_FRONT); Assert.Greater(res, 0, "FeedCard Failed"); bool bRes = reader.EstablishContext(); Assert.True(bRes, "EstablishContext Failed"); bRes = reader.ConnectToCard(); Assert.True(bRes, "Connect Failed"); bRes = reader.WriteToCard("123456"); Assert.True(bRes, "Write To Card Failed"); string read = reader.ReadFromCard(); Assert.AreEqual("123456", read, "Read From Card Failed"); bRes = reader.DisconnectFromCard(); Assert.True(bRes, "Disconnect Failde"); res = ICE_API.SmartCardContinue(printer.Hdc, ICE_API.ICE_SMART_CARD_GOOD); Assert.Greater(res, 0, "SmartCardContinue Failed"); res = ICE_API.EndPage(printer.Hdc); Assert.Greater(res, 0, "End Page Failed"); res = ICE_API.EndDoc(printer.Hdc); Assert.Greater(res, 0, "End Document Failed"); }
The test works, but the principles are violated - it tests several functions and many of them. And each next function depends on the result of the previous one. Now we turn to the question: how do I approach unit testing in these circumstances?