(NET) NET (2013)

TDD - Test Driven Development

There are many alternative technology of create high quality code Program Theory, but there are a couple of different approach to debugging and testing software.

I do not use in project below a separate testing project, because this project is interactive console application. It is possible to emulate console in test project, but this is a time and efforts. More simple way is use test in the same project with replace various part of code by stub. This way is not accessible alway, for example for continuous deployment special test project is mandatory. But for one developer separate test project is not really a good choice.

Testing drive technology I will show in my program to transformation Russian language site to MultiLanguages site. Real site has thousand pages and a lot. really a lot text literals.



I decide manually create list of file for analyzing, because I want to mark processed files and manually input list is better for TDD. Also I manually created a needed resource in App_GlobalResources (I create empty resource file and copy this file with the needed name to folder App_GlobalResources) - because before I start write this program I pass some files manually. Only after I have understanding my wrong manually way, I decide to continue this task with this program and farther I decide create this article as example of TDD)



Therefore manually this job is impossible. Another mandatory future of this program is translating cache. Because Google and MS Translater distort text, finally I decide change automatically translate to manually edited. Also I decide cache of translated and edited litherals.



Result of my program is changing VB source code and add resource to RESX- file.



So, I hope goal of this program is aware for reader, and I move to the literally TDD. What is means? It means special method to writing program when each function can be tested separately, with full isolation from other part of code. But firstly,please look to my code. It has two classes.

First class is TextService, firstly I add to thos class automatically google translator, and then redefine it to manual translator. And second method is transform Englist text to resource name.


   1:  Imports System.Net.Http
   2:  Imports System.Collections
   3:  Imports System.Web.Script.Serialization
   4:  Imports System.Text.RegularExpressions
   5:  Imports System.Windows.Forms
   6:   
   7:  Public Class FakeTextService
   8:      Inherits TextService
   9:   
  10:      Public Overloads Function GoogleTranslateText(ByVal input As String) As String
  11:          Clipboard.SetText(Mid(input, 2, input.Length - 2))
  12:          Console.BackgroundColor = ConsoleColor.Yellow
  13:          Console.Write("EN>")
  14:          Console.BackgroundColor = ConsoleColor.Black
  15:          Return Console.ReadLine.Replace(vbCrLf, "")
  16:      End Function
  17:   
  18:  End Class
  19:   
  20:   
  21:  Public Class TextService
  22:   
  23:      Public Function TranslatedCacheIsExist(OneRusLiteral As String, ByRef GoogleTranslatedPhrase As String, ByRef ResourseName As String) As Boolean
  24:          Dim CacheFiles() As String = IO.File.ReadAllLines("E:\Projects\Arenda_5\MyArenda\TextToResourse\TextToResourse\Cache.txt")
  25:          For I As Integer = 0 To CacheFiles.Count - 1 Step 3
  26:              If OneRusLiteral = CacheFiles(I) Then
  27:                  Console.Write(" (cache) " & CacheFiles(I + 1))
  28:                  GoogleTranslatedPhrase = CacheFiles(I + 1)
  29:                  ResourseName = CacheFiles(I + 2)
  30:                  Return True
  31:              End If
  32:          Next
  33:          Return False
  34:      End Function
  35:   
  36:      Public Sub TranslatedCacheAdd(OneRusLiteral As String, TranslatedPhrase As String, ResourseName As String)
  37:          Dim CacheFiles() As String = IO.File.ReadAllLines("E:\Projects\Arenda_5\MyArenda\TextToResourse\TextToResourse\Cache.txt")
  38:          Array.Resize(CacheFiles, CacheFiles.Length + 3)
  39:          CacheFiles(CacheFiles.Length - 3) = OneRusLiteral.Replace(vbCrLf, "")
  40:          CacheFiles(CacheFiles.Length - 2) = TranslatedPhrase.Replace(vbCrLf, "")
  41:          CacheFiles(CacheFiles.Length - 1) = ResourseName
  42:          IO.File.WriteAllLines("E:\Projects\Arenda_5\MyArenda\TextToResourse\TextToResourse\Cache.txt", CacheFiles)
  43:      End Sub
  44:   
  45:      Public Function PhraseToName(Phrase As String) As String
  46:          Dim MultiWordLiteral As String = ""
  47:          Dim Reg2 As New Regex("( [a-z])")
  48:          Dim MultiWord As MatchCollection = Reg2.Matches(Phrase)
  49:          If MultiWord.Count > 0 Then
  50:              MultiWordLiteral = Reg2.Replace(Phrase, Function(X) X.Value.ToString.Trim.ToUpper)
  51:          Else
  52:              MultiWordLiteral = Phrase
  53:          End If
  54:          Dim Reg3 As New Regex("([A-Z]|[a-z])*")
  55:          Dim Words As MatchCollection = Reg3.Matches(MultiWordLiteral)
  56:          Dim OnlyLetters As String = ""
  57:          For Each OneWord As Match In Words
  58:              OnlyLetters &= OneWord.Value
  59:          Next
  60:          Return OnlyLetters
  61:      End Function
  62:   
  63:      'Translate.googleapis.com site use is very limited. It only allows about 100 requests per one hour 
  64:      Public Function GoogleTranslateText(ByVal input As String) As String
  65:          ' Set the language from/to in the url (or pass it into this function)
  66:          Dim url As String = String.Format("https://translate.googleapis.com/translate_a/single?client=gtx&sl={0}&tl={1}&dt=t&q={2}", "ru", "en", Uri.EscapeUriString(input))
  67:          Dim httpClient As HttpClient = New HttpClient()
  68:          Dim result As String
  69:          Try
  70:              result = httpClient.GetStringAsync(url).Result
  71:          Catch ex As System.AggregateException
  72:              Console.WriteLine(ex.InnerException)
  73:              Return ""
  74:          End Try
  75:          If result = "" Then
  76:              Threading.Thread.Sleep(500)
  77:              Return ""
  78:          End If
  79:          ' Get all json data
  80:          Dim jsonData = New JavaScriptSerializer().Deserialize(Of List(Of Object))(result)
  81:          ' Extract just the first array element (This is the only data we are interested in)
  82:          Dim translationItems = jsonData(0)
  83:          'Translation Data
  84:          Dim translation As String = ""
  85:          'Loop through the collection extracting the translated objects
  86:          For Each item As Object In translationItems
  87:              'Convert the item array to IEnumerable
  88:              Dim translationLineObject As IEnumerable = TryCast(item, IEnumerable)
  89:              'Convert the IEnumerable translationLineObject to a IEnumerator
  90:              Dim translationLineString As IEnumerator = translationLineObject.GetEnumerator()
  91:              'Get first object in IEnumerator
  92:              translationLineString.MoveNext()
  93:              'Save its value (translated text)
  94:              translation += String.Format(" {0}", Convert.ToString(translationLineString.Current))
  95:          Next
  96:          'Remove first blank character
  97:          If translation.Length > 1 Then
  98:              translation = translation.Substring(1)
  99:          End If
 100:          'Return translation
 101:          Return translation
 102:      End Function
 103:      'JavaScript version of google translator https://github.com/matheuss/google-translate-api
 104:   
 105:  End Class

And this a pretty simple method of testing class. Main request to testing class - code coverage, ie you must cover all methods in your class. But this test is pretty simple, because code has linear structure without nesting one function to another one. In fact this is low level API.


   1:  Module Test
   2:   
   3:      Dim TS As New FakeTextService
   4:   
   5:   
   6:      Public Sub TestFakeTranslate()
   7:          Dim GoogleTranslatedPhrase As String = ""
   8:          Debug.WriteLine(TS.GoogleTranslateText("Активация пользователя"))
   9:      End Sub
  10:   
  11:      Public Sub TestPhraseToName()
  12:          Debug.WriteLine(TS.PhraseToName("HOLIDAY.RU - User Activation"))
  13:      End Sub
  14:   
  15:      Public Sub TestCache1()
  16:          Dim OneRusLiteral As String = "Активация пользователя"
  17:   
  18:          Dim GoogleTranslatedPhrase As String = ""
  19:          Dim ResourseName As String = ""
  20:          If Not TS.TranslatedCacheIsExist(OneRusLiteral, GoogleTranslatedPhrase, ResourseName) Then
  21:              'cache service
  22:              GoogleTranslatedPhrase = "HOLIDAYRUUserctivation"
  23:              TS.TranslatedCacheAdd(OneRusLiteral, GoogleTranslatedPhrase, GoogleTranslatedPhrase)
  24:          End If
  25:      End Sub

Second class Module1 is more sophisticated.


   1:  Imports System.Resources
   2:  Imports System.Text.RegularExpressions
   3:  Imports System.Globalization
   4:   
   5:  Public Class Module1
   6:   
   7:      Dim TS As New FakeTextService
   8:   
   9:      Public Sub Main()
  10:          Dim AllFileList() As String = {}
  11:          Dim RelatedResourceFileList As New ArrayList
  12:          Dim RelatedResourceList As New ArrayList
  13:          GetWorkableFilename(AllFileList, RelatedResourceFileList, RelatedResourceList)
  14:   
  15:          For FileListRowNumber = 0 To AllFileList.Count - 1
  16:              Dim OneFileName As String = AllFileList(FileListRowNumber) 'здесь рождается новая ссьлка на строку, теперь изменение OneFileName уже не меняет llFileList(FileListRowNumber)
  17:              If Not OneFileName.StartsWith("'") Then
  18:                  If ProcessOneSourceVBfile(OneFileName, RelatedResourceList(FileListRowNumber), RelatedResourceFileList(FileListRowNumber)) Then
  19:                      'comment processed file
  20:                      AllFileList(FileListRowNumber) = "'" & OneFileName
  21:                      IO.File.WriteAllLines("E:\Projects\Arenda_5\MyArenda\TextToResourse\TextToResourse\VBfiles.txt", AllFileList)
  22:                  End If
  23:              End If
  24:          Next
  25:   
  26:      End Sub
  27:   
  28:      Public Overridable Sub GetWorkableFilename(ByRef AllFileList() As String, ByRef ResourceFileList As ArrayList, ByRef ResourceList As ArrayList)
  29:          Console.WriteLine(Console.OutputEncoding.EncodingName)
  30:          Console.OutputEncoding = Text.Encoding.UTF8
  31:   
  32:          AllFileList = IO.File.ReadAllLines("E:\Projects\Arenda_5\MyArenda\TextToResourse\TextToResourse\VBfiles.txt")
  33:          Dim RelatedResourceFileList As New ArrayList
  34:          Dim RelatedResourceList As New ArrayList
  35:   
  36:          'E:\Projects\Arenda_5\MyArenda\ArendaNew\ActivateLogin.aspx.vb
  37:          'E:\Projects\Arenda_5\MyArenda\ArendaNew\UserInfo1_Mobile.ascx.vb
  38:          'E:\Projects\Arenda_5\MyArenda\ArendaNew\SubscriptAttention.ashx
  39:          'E:\Projects\Arenda_5\MyArenda\ArendaNew\Old_App_Code\AddAdvertising.vb
  40:   
  41:   
  42:          Array.ForEach(AllFileList, Sub(X)
  43:                                         RelatedResourceList.Add(X.Replace("E:\Projects\Arenda_5\MyArenda\ArendaNew\", "").
  44:                                                                 Replace(".ashx", "_ashx").
  45:                                                                 Replace(".aspx.vb", "_aspx").
  46:                                                                 Replace(".ascx.vb", "_ascx").
  47:                                                                 Replace("Old_App_Code\", "Old_App_Code_").Replace(".vb", ""))
  48:                                         RelatedResourceFileList.Add("E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\" & RelatedResourceList(RelatedResourceList.Count - 1) & ".ru-RU.resx")
  49:                                     End Sub)
  50:          'E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\ActivateLogin_aspx.ru-RU.resx
  51:          'E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\UserInfo1_Mobile_ascx.ru-RU.resx
  52:          'E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\SubscriptAttention_ashx.ru-RU.resx
  53:          'E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\Old_App_Code_AddAdvertising.ru-RU.resx
  54:   
  55:          For Each OneFile As String In RelatedResourceFileList
  56:              If Not My.Computer.FileSystem.FileExists(OneFile) Then
  57:                  Console.WriteLine("FileNotExist " & OneFile)
  58:              End If
  59:          Next
  60:          ResourceFileList = RelatedResourceFileList
  61:          ResourceList = RelatedResourceList
  62:      End Sub
  63:   
  64:   
  65:      Public Overridable Function ProcessOneSourceVBfile(OneFileName As String, RelatedResourceName As String, RelatedResourceFile As String) As Boolean
  66:          Console.OutputEncoding = Text.Encoding.UTF8
  67:          Dim SourceVBCode As String = IO.File.ReadAllText(OneFileName)
  68:          Dim Reg1 As New Regex("""(.|\n)*?""")
  69:          Dim StringLiterals As MatchCollection = Reg1.Matches(SourceVBCode)
  70:          Console.BackgroundColor = ConsoleColor.Blue
  71:          Console.WriteLine(OneFileName & ", match=" & StringLiterals.Count)
  72:          Console.BackgroundColor = ConsoleColor.Black
  73:          Dim IsGoogleStop As Boolean = False
  74:   
  75:          Dim RusLiterals As New ArrayList
  76:          Dim ReplacedResourceString As New ArrayList
  77:   
  78:          For Each OneRusLiteral As Match In StringLiterals
  79:              Dim HasCyrillic As Boolean = OneRusLiteral.Value.Where(Function(X) IsCyrillic(X)).Any
  80:              If HasCyrillic Then
  81:                  Do While True
  82:                      Console.Write(OneRusLiteral.Value.ToString & " [y/n]")
  83:                      Dim YNKey As ConsoleKey = Console.ReadKey(False).Key
  84:                      If YNKey = ConsoleKey.Y Then
  85:   
  86:                          Dim ResourseName As String = ""
  87:                          Dim GoogleTranslatedPhrase As String = ""
  88:                          If Not GetResourceName(OneRusLiteral.Value, ResourseName, GoogleTranslatedPhrase) Then
  89:                              IsGoogleStop = True
  90:                              Exit For
  91:                          Else
  92:                              'check and add resource
  93:                              AddResourceIfNeeded(RelatedResourceFile, ResourseName, OneRusLiteral.Value)
  94:                              AddResourceIfNeeded(RelatedResourceFile.Replace(".ru-RU", ""), ResourseName, GoogleTranslatedPhrase)
  95:                              RusLiterals.Add(OneRusLiteral.Value)
  96:                              ReplacedResourceString.Add("Resources." & RelatedResourceName & "." & ResourseName)
  97:                          End If
  98:   
  99:                          Exit Do
 100:                      ElseIf YNKey = ConsoleKey.N Then
 101:                          Exit Do
 102:                      End If
 103:                  Loop
 104:                  Console.WriteLine()
 105:              End If
 106:          Next
 107:          'replace all Rus literal to regerence with resource
 108:          ReplaceSourceVBcode(OneFileName, SourceVBCode, RusLiterals, ReplacedResourceString)
 109:          If IsGoogleStop Then Return False Else Return True
 110:      End Function
 111:   
 112:      Public Function GetResourceName(OneRusLiteral As String, ByRef ResourseName As String, ByRef GoogleTranslatedPhrase As String) As Boolean
 113:   
 114:          If Not TS.TranslatedCacheIsExist(OneRusLiteral, GoogleTranslatedPhrase, ResourseName) Then
 115:              'cache service
 116:              GoogleTranslatedPhrase = TS.GoogleTranslateText(OneRusLiteral)
 117:              If GoogleTranslatedPhrase = "" Then
 118:                  ' translate.googleapis.com site use is very limited. It only allows about 100 requests per one hour 
 119:                  Return False
 120:              End If
 121:              ResourseName = TS.PhraseToName(GoogleTranslatedPhrase)
 122:              TS.TranslatedCacheAdd(OneRusLiteral, GoogleTranslatedPhrase, ResourseName)
 123:          Else
 124:              ResourseName = TS.PhraseToName(GoogleTranslatedPhrase)
 125:          End If
 126:          Return True
 127:      End Function
 128:   
 129:   
 130:      Public Sub AddResourceIfNeeded(RelatedResourceFile As String, ResourseName As String, TXT As String)
 131:          'https://docs.microsoft.com/en-us/dotnet/framework/resources/working-with-resx-files-programmatically
 132:          If ResourseName = "" Then
 133:              Throw New Exception("ResourseName Is empty")
 134:          End If
 135:          'The previous resources entries will be overwrited if we write the the same resource file again
 136:          Dim Resource As New List(Of KeyValuePair(Of String, String))
 137:          Dim IsResourceExist As Boolean = False
 138:          Dim ExistResource As ResXResourceSet = New ResXResourceSet(RelatedResourceFile)
 139:          If ExistResource.GetString(ResourseName) IsNot Nothing Then
 140:              IsResourceExist = True
 141:          Else
 142:              Dim Enums As IDictionaryEnumerator = ExistResource.GetEnumerator
 143:              While Enums.MoveNext
 144:                  Resource.Add(New KeyValuePair(Of String, String)(Enums.Key, Enums.Value))
 145:              End While
 146:          End If
 147:          ExistResource.Close()
 148:          If Not IsResourceExist Then
 149:              Dim ResxFile As ResXResourceWriter = New ResXResourceWriter(RelatedResourceFile)
 150:              For Each OneRes As KeyValuePair(Of String, String) In Resource
 151:                  ResxFile.AddResource(OneRes.Key, OneRes.Value)
 152:              Next
 153:              ResxFile.AddResource(ResourseName, TXT)
 154:              ResxFile.Generate()
 155:              ResxFile.Close()
 156:          End If
 157:      End Sub
 158:   
 159:      Public Overridable Sub ReplaceSourceVBcode(OneFileName As String, SourceVBCode As String, RusLiterals As ArrayList, ReplacedResourceString As ArrayList)
 160:          For i As Integer = 0 To RusLiterals.Count - 1
 161:              SourceVBCode = Replace(SourceVBCode, RusLiterals(i), ReplacedResourceString(i))
 162:          Next
 163:          IO.File.WriteAllText(OneFileName, SourceVBCode)
 164:      End Sub
 165:   
 166:      Public Function IsCyrillic(c As Char) As Boolean
 167:          Return AscW(c) >= &H410 And AscW(c) <= &H44F
 168:      End Function
 169:   
 170:  End Class

Low level API is only two method GetWorkableFilename and AddResourceIfNeeded. Other low level API is ReplaceSourceVBcode, but for method is so difficult to testing separately, more simple way is call this method with high level APi and check a result in ASP.NET project. Another low level function is IsCyrillic, but it testing as part of ProcessOneSourceVBfile. Other function is high level of API, it contains execution of cf low level API in the same class and from class FakeTextService.

And below you can see a testing class. See it carefully, to understand how I have isolated nested low level calling function and how I organize function to be called testing method.


   1:  Module Test
   ...   
  27:      Public Sub TestCache2()
  28:          Dim MD As New Module1
  29:          Dim ResourseName As String = ""
  30:          Dim GoogleTranslatedPhrase As String = ""
  31:          MD.GetResourceName("В ОТПУСК.РУ - Активация пользователя", ResourseName, GoogleTranslatedPhrase)
  32:          MD.GetResourceName("Аренда", ResourseName, GoogleTranslatedPhrase)
  33:          MD.GetResourceName("Dos атака", ResourseName, GoogleTranslatedPhrase)
  34:          MD.GetResourceName("Активация пользователя", ResourseName, GoogleTranslatedPhrase)
  35:          Debug.WriteLine(ResourseName)
  36:      End Sub
  37:   
  38:      Public Sub TestGetWorkableFilename()
  39:          Dim MD As New FakeProcessOneSourceVBfile
  40:          Dim AllFileList() As String = {}
  41:          Dim RelatedResourceFileList As New ArrayList
  42:          Dim RelatedResourceList As New ArrayList
  43:          MD.GetWorkableFilename(AllFileList, RelatedResourceFileList, RelatedResourceList)
  44:          Debug.Print(AllFileList(0))
  45:          Debug.Print(RelatedResourceFileList(0))
  46:          Debug.Print(RelatedResourceList(0))
  47:          'E:\Projects\Arenda_5\MyArenda\ArendaNew\ActivateLogin.aspx.vb
  48:          'E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\ActivateLogin_aspx.ru-RU.resx
  49:          'ActivateLogin_aspx
  50:      End Sub
  51:   
  52:      Public Sub TestMainSub()
  53:          Dim MD As New FakeGetWorkableFilename
  54:          MD.Main()
  55:      End Sub
  56:   
  57:      Public Sub TestAddResourceIfNeeded1()
  58:          Dim MD As New Module1
  59:          MD.AddResourceIfNeeded("E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\ActivateLogin_aspx.ru-RU.resx", "RentProperty", "Аренда")
  60:          MD.AddResourceIfNeeded("E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\ActivateLogin_aspx.ru-RU.resx", "RentProperty", "Аренда")
  61:      End Sub
  62:   
  63:      Public Sub TestAddResourceIfNeeded2()
  64:          Dim MD As New Module1
  65:          MD.AddResourceIfNeeded("E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\ActivateLogin_aspx.ru-RU.resx", "RentProperty", "Аренда")
  66:          MD.AddResourceIfNeeded("E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\ActivateLogin_aspx.ru-RU.resx", "InvalidParametersSpecified", "Указаны неверные параметры")
  67:      End Sub
  68:   
  69:      Public Sub TestReplaceSourceVBcode()
  70:          Dim MD As New FakeReplaceSourceVBcode
  71:          MD.ProcessOneSourceVBfile("E:\Projects\Arenda_5\MyArenda\ArendaNew\ActivateLogin.aspx.vb", "ActivateLogin_aspx", "E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\ActivateLogin_aspx.ru-RU.resx")
  72:      End Sub
  73:   
  74:      Public Sub TestProcessOneSourceVBfile()
  75:          Dim MD As New Module1
  76:          MD.ProcessOneSourceVBfile("E:\Projects\Arenda_5\MyArenda\ArendaNew\User.aspx.vb", "User_aspx", "E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\User.aspx.ru-RU.resx")
  77:      End Sub
  78:   
  79:      Public Sub Main()
  80:          Dim MD As New Module1
  81:          MD.Main()
  82:      End Sub
  83:   
  84:   
  85:  End Module
  86:   
  87:  Public Class FakeGetWorkableFilename
  88:      Inherits FakeProcessOneSourceVBfile
  89:   
  90:      Public Overloads Overrides Sub GetWorkableFilename(ByRef AllFileList() As String, ByRef ResourceFileList As ArrayList, ByRef ResourceList As ArrayList)
  91:          Dim AllFile() As String = {"E:\Projects\Arenda_5\MyArenda\ArendaNew\ActivateLogin.aspx.vb"}
  92:          Dim FileList As New ArrayList
  93:          FileList.Add("E:\Projects\Arenda_5\MyArenda\ArendaNew\App_GlobalResources\ActivateLogin_aspx.ru-RU.resx")
  94:          Dim List As New ArrayList
  95:          List.Add("ActivateLogin_aspx")
  96:          AllFileList = AllFile
  97:          ResourceFileList = FileList
  98:          ResourceList = List
  99:      End Sub
 100:   
 101:  End Class
 102:   
 103:  Public Class FakeProcessOneSourceVBfile
 104:      Inherits FakeReplaceSourceVBcode
 105:   
 106:      Public Overloads Overrides Function ProcessOneSourceVBfile(OneFileName As String, RelatedResourceName As String, RelatedResourceFile As String) As Boolean
 107:          Return True
 108:      End Function
 109:   
 110:  End Class
 111:   
 112:  Public Class FakeReplaceSourceVBcode
 113:      Inherits Module1
 114:   
 115:      Public Overloads Overrides Sub ReplaceSourceVBcode(OneFileName As String, SourceVBCode As String, RusLiterals As ArrayList, ReplacedResourceString As ArrayList)
 116:          For i As Integer = 0 To RusLiterals.Count - 1
 117:              SourceVBCode = Replace(SourceVBCode, RusLiterals(i), ReplacedResourceString(i))
 118:          Next
 119:          Debug.WriteLine(SourceVBCode)
 120:      End Sub
 121:   
 122:  End Class

For testing I permanently, step-by-step changed entry point (function MAIN) form one function to another. This renaming is disadvantage of TDD-testing in the same project, because if you create test in separate project each testing method is calling separately (testing project can contains many methods), but this program is interactive, not a simple class. And write a simulator of console input and output and isolate input/output from other part of code need a time. For enterprise project and continuous delivery separate test project is mandatory job, but for this project this is only dumb waste of time. I want to coverage all function in class Module1 and a I done this for 100% by simplest way.



Comments ( )
Link to this page: //www.vb-net.com/TDD/Index.htm
< THANKS ME>