Meine Fragen zu AccUnit

Testen von Access-Anwendungen

Meine Fragen zu AccUnit

Beitragvon Andreas Vogt » Do 4. Jun 2015, 09:45

Hallo,
um private Methoden und Eigenschaften einer Klasse testen zu können müsste ich diese als Friend bzw. public deklarieren?
Gibt es eine Möglichkeit z.B. per Compileranweisung dies zu handeln, so dass wenn ich nicht teste dass die Prozeduren wieder Private werden?
Bzw. wenn ich die Testumgebung entferne, dass dann wieder private verwendet wird?
Oder werden private Properties und Prozeduren in Klassen nicht getestet weil diese ja durch das Testen der Öffentlichen Methoden/Eigenschaften getestet werden?

Ist es möglich die Reihenfolge von Tests zu definieren? Oder werden diese in der Reihenfolge ausgeführt wie sie in der Testklasse stehen?
Beispiel Testen von OptionManager.SettingByName sollte vor OptionManager.DeleteByName ausgeführt werden um einen eingefügten Key wieder zu löschen.
Btw: Habe eben durch das Testen herausgefunden dass in der Prozedur DeleteByName nach dem Execute ein CatchOptionValue fehlt, sonst bleibt der gelöschte Key im Array bestehen. 8-)

to be continued

Gruß Andreas
Andreas Vogt
Entwickler
 
Beiträge: 165
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Re: Meine Fragen zu AccUnit

Beitragvon Josef Pötzl » Do 4. Jun 2015, 12:49

Hallo!

Private Methoden lassen sich mit AccUnit nicht testen.
Wenn eine Methode getestet werden soll, ist sie vermutlich auch wichtig genug, um sie public zu machen.

Ausnahme: eine private Methode soll während der Klassenentwicklung getestet werden => in so einem Fall würde ich mir in der Klasse eine testbare Public-Methode einbauen, die die private Methode entsprechend aufbaut und eventuell noch passende Test-Parameter in die Klasse einbringen kann. ... so ein Vorgehen nutzte ich selbst nicht, ich könnte mir aber vorstellen, dass ich so etwas einsetze um einen Fehler zu finden.
Grundsätzlich sollte es meiner Meinung nach aber ausreichen, die public-Methoden zu testen - denn alles andere ist vom Innenleben der Klasse abhängig und kann sowieso von außen nicht beeinflusst werden.

Code: Alles auswählen
Ist es möglich die Reihenfolge von Tests zu definieren?

Eine Reihenfolge sollte nicht notwendig sein - genau genommen, darf sie nicht notwendig sein, da das bedeuten würde, dass die Tests voneinander abhängig sind.

Um beim Beispiel SettingByName und DeleteByName zu bleiben: Du müsstest über im Test sicherstellen, dass genau der zu prüfende Wert in der Tabelle vorhanden ist - egal ob du SettingByName oder DeleteByName prüfst.
Interessant wird das Testen der Enums - da diese eigentlich über Test erstellt und dann geprüft werden müssten. Da bin ich gespannt, ob das der Compiler mitmacht (Code-Änderung während einer Code-Ausführung im gleichen Projekt).

mfg
Josef
Josef Pötzl
Moderator
 
Beiträge: 805
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2016

Re: Meine Fragen zu AccUnit

Beitragvon Andreas Vogt » Do 4. Jun 2015, 14:23

Hallo,
hier meine Testklasse zur OptionManager Klasse:

Code: Alles auswählen
Option Compare Text
Option Explicit

'AccUnit:TestClass

' AccUnit infrastructure for advanced AccUnit features. Do not remove these lines.
Implements SimplyVBUnit.ITestFixture
Implements AccUnit_Integration.ITestManagerBridge
Private TestManager As AccUnit_Integration.TestManager
Private Sub ITestManagerBridge_InitTestManager(ByVal NewTestManager As AccUnit_Integration.ITestManagerComInterface): Set TestManager = NewTestManager: End Sub
Private Function ITestManagerBridge_GetTestManager() As AccUnit_Integration.ITestManagerComInterface: Set ITestManagerBridge_GetTestManager = TestManager: End Function
Private Sub ITestFixture_AddTestCases(ByVal Tests As SimplyVBUnit.TestCaseCollector): TestManager.AddTestCases Tests: End Sub

'--------------------------------------------------------------------
' Tests
'--------------------------------------------------------------------

Public Sub SettingByName_InsertedKey_OutputKeyValue()
    ' Arrange
   Const KeyName As String = "TestKey1"
    Const TestValue As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
    Dim Actual As String
    ' Act
   OptionManager.SettingByName(KeyName) = TestValue
    Actual = OptionManager.SettingByName(KeyName)
    OptionManager.DeleteByName KeyName
   
    ' Assert
   Assert.That Actual, Iz.EqualTo(TestValue)
End Sub

Public Sub Setting_InsertedKeyValueBefore_EnumItemValueNotvbNullString()
    ' Arrange
   Const KeyName As String = "TestKey1b"
    Const TestValue As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
    Dim Actual As String
   
    ' Act
   OptionManager.SettingByName(KeyName) = TestValue
    Actual = OptionManager.Setting(1)
    OptionManager.DeleteByName KeyName
   
    ' Assert
   Assert.That Actual, Iz.not.EqualTo(vbNullString)
End Sub

Public Sub Setting_ChangedEnumItemValue_EnumItemValueEqualNewValue()
    ' Arrange
   Const newValue As String = "test_4711"
    Dim oldValue As String
    Dim expectedValue As String
   
    ' Act
   oldValue = OptionManager.Setting(1) 'ein Item mit Index >=1 ist nach dem Input oben vorhanden!
   OptionManager.Setting(1) = newValue
    expectedValue = OptionManager.Setting(1)
    OptionManager.Setting(1) = oldValue
   
    ' Assert
   Assert.That newValue, Iz.EqualTo(expectedValue)
End Sub

Public Sub DeleteByName_InsertedKeyValueBefore_KeyDeleted()
    ' Arrange
   Dim getValue As String
    Const KeyName As String = "TestKey1"
   
    ' Act
   OptionManager.SettingByName(KeyName) = vbNullString
    OptionManager.DeleteByName KeyName
    getValue = OptionManager.SettingByName(KeyName)
   
    ' Assert
   Assert.That getValue, Iz.EqualTo(vbNullString)
End Sub

Public Sub KeyName_CreatedEnumKey_EnumKeyExpected()
    ' Arrange
   Const NewKeyName As String = "test_key2"
    Dim ActualKeyName As String
    Dim lastIndex As Long
   
    ' Act
   OptionManager.SettingByName(NewKeyName) = ""
    lastIndex = DCount("*", OptionManager.DataSource)
    ActualKeyName = OptionManager.KeyName(lastIndex)
    OptionManager.DeleteByName NewKeyName
   
    ' Assert
   Assert.That ActualKeyName, Iz.EqualTo(NewKeyName)
End Sub

Public Sub Count_RowNumInsertPlus1_NumberOfRows()
    ' Arrange
   Const NewKeyName As String = "test_key3"
    Dim lastIndex As Long
    Dim expectedValue As Long

    ' Act
   lastIndex = DCount("*", OptionManager.DataSource) + 1
    OptionManager.SettingByName(NewKeyName) = vbNullString
    expectedValue = OptionManager.Count
    OptionManager.DeleteByName NewKeyName
   
    ' Assert
   Assert.That lastIndex, Iz.EqualTo(expectedValue)
End Sub

Public Sub DataSource_Tabname_IsNotvbNullString()
    ' Arrange
   Dim TabName As String
   
    ' Act
   TabName = OptionManager.DataSource
   
    ' Assert
   Assert.That TabName, Iz.not.EqualTo(vbNullString)
End Sub

'letzte Testmethode in der Testklasse, danach keine Tests möglich wg. Class.Terminate
Public Sub UpdateEnum_CreatedEnumItem_EnumItemValueNotvbNullString()
    ' Arrange
   Dim lastIndex As Long
    Dim Output As String
    lastIndex = DCount("*", OptionManager.DataSource) + 1
   
    ' Act
   OptionManager.SettingByName("test_Key1") = "4711"
    OptionManager.UpdateEnum
    Output = OptionManager.Setting(lastIndex)
    OptionManager.DeleteByName "test_Key1"
    OptionManager.UpdateEnum
   
    ' Assert
   Assert.That Output, Iz.not.EqualTo(vbNullString)
End Sub


Die Tests sind jetzt unabhängig von einander bis auf CreateEnum, nach diesem Test funktioniert kein anderer mehr?!

Andreas
Andreas Vogt
Entwickler
 
Beiträge: 165
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Re: Meine Fragen zu AccUnit

Beitragvon Josef Pötzl » Do 4. Jun 2015, 17:04

Damit UpdateEnum getestet werden kann, müsste man vermutlich in einer anderen Access-Anwendung den Code einfügen, dort die Optionmanager-Instanz nutzen und UpdateEnum ausführen, damit die Test-Instanz nicht von der Code-Änderung betroffen ist.

LG
Josef
Josef Pötzl
Moderator
 
Beiträge: 805
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2016

Re: Meine Fragen zu AccUnit

Beitragvon Andreas Vogt » Do 4. Jun 2015, 17:58

Solange man den UpdateEnum-Test an das Ende der Testklasse schreibt, funktionieren ja dieser Test.
Es wird ein zusätzlicher Schlüssel eingefügt, danach wird der Enum aktualisiert und dieser getestet indem man Setting() mit einem Index-Wert > als der vor dem Schlüssel einfügen existierende Indexwert abruft. ist dieser Index vorhanden hat der Test geklappt. Ich denke das ist ausreichend genug - oder?

Andreas
Andreas Vogt
Entwickler
 
Beiträge: 165
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Re: Meine Fragen zu AccUnit

Beitragvon Josef Pötzl » Do 4. Jun 2015, 19:11

Der Test läuft bei dir durch?
Mach bitte einmal als Prüfung ein Assert, das fehl schlagen muss.

Ich würde einen Test, der nur zum Schluss ausgeführt werden kann, weglassen oder zumindest auf "Ignore" setzen, damit er im normalen Testdurchlauf nicht ausgeführt wird.

Was testest du in dieser Test-Prozedur eigentlich?

LG
Josef
Josef Pötzl
Moderator
 
Beiträge: 805
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2016

Re: Meine Fragen zu AccUnit

Beitragvon Andreas Vogt » Do 4. Jun 2015, 21:08

Hallo,
ja läuft anstandslos durch, alles grün.
BTW: meine Testklasse ist noch fehlerhaft, vbNullString ist durch "0" zu ersetzen weil sonst der Test bei DeleteByName() nicht funktioniert.
Denk auch daran an die Änderung bei DeleteByName() die ich heute hochgestellt habe. Nach dem Execute muss ein CatchOptionValue stehen.
Was testest du in dieser Test-Prozedur eigentlich?

Meinst du damit die Prozedur Update Enum?
Die kann man ja eigentlich nur testen, indem man einen neuen Datensatz einfügt, UpdateEnum ausführt, und nachsieht ob der Enum-Wert in das Helper-Modul eingefügt wurde.
Und das kann man testen indem man die OptionManager.Setting(Index) ausführt, mit einem Index der um 1 größer ist wie die Anzahl Datensätze vor dem "Datensatz hinzufügen"

Hab das gerade mal mit einem erzwungenem Fehler getestet indem ich eben kein neuen Datensatz vorher eingefügt habe. Dann wäre der Index nämlich außerhalb des gültigen Bereichs.
Und Tatsächlich, der Test liefert dann "error 9, Index außerhalb des gültigen Bereichs"

Für mich funktioniert der Test einwandfrei und zeigt dass die Prozedur "UpdateEnum" auch in Ordnung ist.

Andreas
Andreas Vogt
Entwickler
 
Beiträge: 165
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Re: Meine Fragen zu AccUnit

Beitragvon Andreas Vogt » Do 4. Jun 2015, 22:34

So sieht die Testliste bei mir aus:

Bild
Andreas Vogt
Entwickler
 
Beiträge: 165
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Re: Meine Fragen zu AccUnit

Beitragvon Josef Pötzl » Fr 5. Jun 2015, 10:23

Hallo!

Du testest mit diesem Code aber nicht die Enum-Erstellung, sondern im Prinzip nur, ob Insert und Delete funktioniert.
Wenn du die Zeilen mit UpdateEnum weg lässt, läuft der Test durch. somit dürfte die Update-Methode eine leere Methode sein. ;)

mfg
Josef
Josef Pötzl
Moderator
 
Beiträge: 805
Registriert: Mo 30. Nov 2009, 10:08
Wohnort: Klagenfurt
Accessversion: 2016

Re: Meine Fragen zu AccUnit

Beitragvon Andreas Vogt » Fr 5. Jun 2015, 11:37

Ich kann ja schlecht das Modul öffnen und die Enum Items zählen lassen.
Aber du hast recht, UpdateEnum ist nicht testbar.

Andreas
Andreas Vogt
Entwickler
 
Beiträge: 165
Registriert: Do 18. Mär 2010, 18:00
Wohnort: Offenburg
Accessversion: 2.0, 97, 2002, 2003, 2007, 2010
Access-Erfahrung: Fortgeschritten

Nächste

Zurück zu AccUnit

cron