none
Kombinationen für NUnit-Test erstellen RRS feed

  • Frage

  • Hallo zusammen,

    für einen NUnit-Test wollte ich alle Kombinationen für meine Test-Input-Parameter auflisten (siehe Format im C#-Beispiel unten):

    public void CombinatorialTest(Condition condition, Types type, bool value1, bool value2)

    Condition und Types sind enums

    I hatte es mit NUnits [Test, Combinatorial] zunächst versucht, bin aber aufgrund des speziellen Musters für den Test-Input gescheitert. Ich habe dann eine anderen Weg eingeschlagen und habe versucht, mir den Test-Input über eine TestCaseSource zusammenzustellen.

    Leider klappt das aber auch nicht so, wie ich will, weil die BooleanValues mehr oder weniger als eine Art Tupel noch korrekt kombiniert werden sollen. Zunächst bin ich über verschiedene geschachtelte Schleifen mit yield return gegangen, was ich aber etwas unschön fand. Jetzt ein Versuch wie hier, bei dem ich gerne die Elemente eines IEnumerable per yield return jeweils als Element in das object-Array mit aufnehmen möchte. Geht das?

    using NUnit.Framework;
    using System;
    using System.Collections.Generic;
    using System.Linq;

    namespace Permutations
    {
        [TestFixture]
        class MyTest
        {
            [TestCaseSource("Combinations")]
            public void CombinatorialTest(Condition condition, Types typeClass, bool value1, bool value2)
            {
                Console.WriteLine($"Condition: {condition}, TypeClass: {typeClass}, Bool_1: {value1}, Bool_2: {value2}");
                // do Asserts later on
            }

            public static IEnumerable<object[]> Combinations()
            {
                foreach (var conditionValue in ConditionValues())
                {
                    // Condition.A, Type_A, false, false
                    // Condition.A, Type_A, false, true
                    // Condition.A, Type_A, true, false
                    // Condition.A, Type_A, true, true
                    // Condition.A, Type_B, false, false
                    // Condition.A, Type_B, false, true
                    // Condition.A, Type_B, true, false
                    // Condition.A, Type_B, true, true
                    // Condition.A, Type_C, false, false
                    // Condition.A, Type_C, false, true
                    // Condition.A, Type_C, true, false
                    // Condition.A, Type_C, true, true
                    // Condition.B, Type_A, false, false
                    // Condition.B, Type_A, false, true
                    // ...
                    foreach (var typeClass in TypeClassValues())
                    {
                        yield return new object[] { conditionValue, typeClass, BooleanValues().ToArray().Select(x => x), BooleanValues().ToArray().Select(x => x) };
                    }

                    // Type_A, Condition.A, false, false
                    // Type_A, Condition.A, false, true
                    // Type_A, Condition.A, true, false
                    // Type_A, Condition.A, true, true
                    // Type_A, Condition.B, false, false
                    // Type_A, Condition.B, false, true
                    // Type_A, Condition.B, true, false
                    // Type_A, Condition.B, true, true
                    // ...
                    // Type_B, Condition.A, false, false
                    // Type_B, Condition.A, false, true
                    // ...
                    foreach (var typeClass in TypeClassValues())
                    {
                        yield return new object[] { typeClass, conditionValue, BooleanValues().Distinct(), BooleanValues().Distinct() };
                    }
                }
            }
            
            private static IEnumerable<Condition> ConditionValues()
            {
                yield return Condition.A;
                yield return Condition.B;
                yield return Condition.C;
                yield return Condition.D;
            }

            private static IEnumerable<Types> TypeClassValues()
            {
                yield return Types.Type_A;
                yield return Types.Type_B;
                yield return Types.Type_C;
            }

            private static IEnumerable<bool> BooleanValues()
            {
                yield return false;
                yield return true;
            }
        }

        enum Condition
        {
            A,
            B,
            C,
            D,
        }

        enum Types
        {
            Type_A,
            Type_B,
            Type_C,
        }
    }

    Samstag, 16. November 2019 15:18

Alle Antworten

  • Hallo CSharpDeveloper_OXO,

    Versuchst Du, eine Auflistung nach jeder Bedingung zu filtern, während die Typensicherheit noch besteht? Du kannst dies erreichen, indem Du die Filtermethode implementierst, die die generische Version des Prädikats verwendet, wie in diesem Artikel beschrieben wird:
    Learning C# through LINQ

    Gruß,

    Ivan Dragov


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.


    Montag, 18. November 2019 13:03
    Moderator
  • Im Prinzip hatte ich versucht alle Booleschen Kombinationen aufzulisten und diese dann jeweils einzeln zum bestehenden object[] in der Methode Combinations() hinzuzufügen und bei jedem Schritt jeweils eine Zeile dieses Arrays mit yield return zurück zu geben:

    In der Schleife wird ja zunächst im Prinzip die Auflistung mit den Werten wie folgt aufgebaut:

    { Condition.A, Type_A }
    { Condition.A, Type_B }

    { Condition.B, Type_A }
    { Condition.B, Type_B }

    Irgendwie wollte ich dann zuerst die Booleschen Kombinationen holen

    { false, false }
    { false, true }
    { true, false }
    { true, true }

    und diese dann noch einfach jeweils einzeln {false, false } ... {true, true} mit zu den Kombinationen {Condition.A, Type_A} ... {Condition.D, Type_C} anzuhängen.

    Vielleicht ist es aber bei nur 2 Auflistungen mit Werte von true und false wirklich selber alle Kombinationen hinzuschreiben und jeweils diese Elemente aus dem object[] per yield return raus zu geben:

    foreach (var conditionValue in ConditionValues())
    {
         // Condition.A, Type_A, false, false
         // Condition.A, Type_A, false, true
         // Condition.A, Type_A, true, false
         // Condition.A, Type_A, true, true
         // Condition.A, Type_B, false, false
         // Condition.A, Type_B, false, true
         // Condition.A, Type_B, true, false
         // Condition.A, Type_B, true, true
         // Condition.A, Type_C, false, false
         // Condition.A, Type_C, false, true
         // Condition.A, Type_C, true, false
         // Condition.A, Type_C, true, true
         // Condition.B, Type_A, false, false
         // Condition.B, Type_A, false, true
         // ...
         foreach (var typeClass in TypeClassValues())
         {
             yield return new object[] { conditionValue, typeClass, false, false };
             yield return new object[] { conditionValue, typeClass, true, false };
             yield return new object[] { conditionValue, typeClass, false, true};
             yield return new object[] { conditionValue, typeClass, true, true };
         }

         ...

    }

    Anders schaut es aber dann aus, wenn wir nicht mit Booleschen Werten, sondern einer größeren Auflistung gearbeitet hätten. Dann wäre das mit einzeln auflisten eher ein Unding.

    Dienstag, 19. November 2019 07:34