none
Getting all combinations for Test RRS feed

  • Question

  • Hi all,

    for an NUnit-Test I want to have all combinations for my Test-Input-Parameters in a special format (see comments below):

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

    Condition and Types are enums

    I tried with NUnits combinatorial Testing, but as there is a special pattern for my test input, I don't know, if I can get that done with NUnit Combinatorial Testing and tried a pure csharp solution to generate the Test-Input.

    Unfortunately, this doesn't generate the right Input correctly and I think its also because the BooleanValues are not combined correctly and returned as single Elements. The job could have been done with nested more nested loops in method Combinations(), but that's also ugly code then:

    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,
        }
    }


    Saturday, November 16, 2019 7:47 AM

All replies

  • Hi friend,

    Sorry for delay in reply.

    As far as I know, the BooleanValues().ToArray().Select(x => x) will return a new  IEnumerable<T>, which could not be cast to a bool value. Please refer: Enumerable.Select Method

    So we suggest you could use a loop to access all elements from BooleanValues(), please refer this sample:

    foreach (var typeClass in TypeClassValues())
    {
       bool[] Bvalue = BooleanValues().Select(x => x).ToArray();
       int i = 0;
       while(i<2)
       {
           yield return new object[] { conditionValue, typeClass, Bvalue[i], Bvalue[0] };
           yield return new object[] { conditionValue, typeClass, Bvalue[i], Bvalue[1] };
           i++;
        }
    }

    Hope it could help you.

    Best Regards,

    Dylan


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com


    Monday, November 18, 2019 11:36 AM
  • Okay, so I need the loop anyway, which I wanted to avoid originally :)

    The thing is, how to I attach the single values to the object[] { ... } in method Combinations()

    I just did it in a simpler way now and listed the Boolean values directly in Combinations(). But this just works well since the Boolean Values only have 2 different elements. In case we had 3 values this would already be a different story then and I almost assume there is no way around nested loops then, right?

    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 };
         }

         ...

    }

    Tuesday, November 19, 2019 7:40 AM
  • Hi friend,

    Sorry for delay in reply.

    Yes, if the volume is three or more, the nested loop would be not a good choice. I try to look for a fast method to go through IEnumerable, then transfer the all arrangement combinations of all values into object[], but they just work for single or 2 values.

    BTW, I found a answer about the relationship between IEnumerable and foreach loop:Fastest way to iterate through an IEnumerable<T>

    Hope it could help you. 

    Best Regards,

    Dylan


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com

    Wednesday, November 20, 2019 9:42 AM