Ist die Definition TestMethod im test Basis-Klassen nicht unterstützt, MsTest?

Diese Frage betrifft ein Allgemeines unit-test-Technik mit potentiell sehr nützlich Breite Palette von Szenarien anwendbar. Aber es ist leichter zu verstehen mit einem Beispiel zu illustrieren meine Frage besser.

Sagen wir, ich will, um zu testen, dass alle Typen, überschreiben Equals() nicht so richtig. Da Equals() ist definiert als virtuelle System.Object eine große Auswahl an Typen können sich ändern, das Verhalten. Jeder Typ, der das tut, wird haben tests, um sicherzustellen, dass das neue Verhalten folgt die implizite Erwartungen an einen Aufrufer dieser Methode. Speziell für Equals(), wenn Sie überschreiben diese Methode mit der neuen Implementierung muss sicherstellen, dass zwei gleiche Objekte müssen gleiche hash-codes, definiert durch System.Object.GetHashCode().

Damit zu erzwingen, mehrere test-Klassen benötigt werden, und Sie werden alle test für die gleiche Konsistenz von Verhalten über alle diese Typen.

Zu vermeiden, re-geben Sie alle TestMethods erforderlich, um zu testen, wie Typ-I-stattdessen definieren Sie eine Basis-test-Klasse, die sieht aus wie unten, und haben diese test-Klassen Erben alle das gleiche Verhalten test-suite:

///<summary>
///Test fixture base class for testing types that overrides Object.Equals()
///</summary>
///<typeparam name="T">The production type under test</typeparam>
public abstract class EqualsFixtureBase<T>
{
    #region Equals tests

    protected static void CompareInstances(T inst1, T inst2, bool expectedEquals)
    {
        Assert.AreEqual(expectedEquals, inst1.Equals((T)inst2));
        Assert.AreEqual(expectedEquals, inst1.Equals((object)inst2));
        if (expectedEquals)
        {
            //equal instances MUST have identical hash codes
            //this is a part of the .NET Equals contract
            Assert.AreEqual(inst1.GetHashCode(), inst2.GetHashCode());
        }
        else
        {
            if (inst2 != null)
            {
                Assert.AreNotEqual(inst1.GetHashCode(), inst2.GetHashCode());
            }
        }
    }

    ///<summary>
    ///Creates version 1 instance of the type under test, not 'Equal' to instance 2.
    ///</summary>
    ///<returns>An instance created with properties 1.</returns>
    protected abstract T CreateInstance1();

    ///<summary>
    ///Creates version 2 instance of the type under test, not 'Equal' to instance 1.
    ///</summary>
    ///<returns>An instance created with properties 2.</returns>
    protected abstract T CreateInstance2();

    ///<summary>
    ///Creates an instance equal to the version 1 instance, but not the identical
    ///same object.
    ///</summary>
    ///<returns>An instance created with properties equal to instance 1.</returns>
    protected abstract T CreateInstanceThatEqualsInstance1();

    [TestMethod]
    public void Equals_NullOrDefaultValueTypeInstance()
    {
        T instance = CreateInstance1();
        CompareInstances(instance, default(T), false);
    }

    [TestMethod]
    public void Equals_InstanceOfAnotherType()
    {
        T instance = CreateInstance1();
        Assert.IsFalse(instance.Equals(new object()));
    }

    [TestMethod]
    public void Equals_SameInstance()
    {
        T slot1 = CreateInstance1();
        CompareInstances(slot1, slot1, true);
    }

    [TestMethod]
    public void Equals_EqualInstances()
    {
        T slot1 = CreateInstance1();
        T slot2 = CreateInstanceThatEqualsInstance1();
        CompareInstances(slot1, slot2, true);
        CompareInstances(slot2, slot1, true);
    }

    [TestMethod]
    public void Equals_NonEqualInstances()
    {
        T slot1 = CreateInstance1();
        T slot2 = CreateInstance2();
        CompareInstances(slot1, slot2, false);
        CompareInstances(slot2, slot1, false);
    }

    #endregion Equals tests
}

Kann ich dann wiederverwenden, diese TestMethods für jeden Typ überschreiben von Equals(). Zum Beispiel, das wäre der test-Klasse definition für die Prüfung, dass die System.String Typ implementiert Equals() richtig.

[TestClass]
public class ExampleOfAnEqualsTestFixture : EqualsFixtureBase<string>
{
    [TestMethod]
    public void Foo()
    {
        Assert.IsTrue(true);
    }

    protected override string CreateInstance1()
    {
        return "FirstString";
    }

    protected override string CreateInstance2()
    {
        return "SecondString";
    }

    protected override string CreateInstanceThatEqualsInstance1()
    {
        return "FirstString";
    }
}

Diese können auch erweitert werden. Zum Beispiel für Arten, die überlastung der == und != die Betreiber, eine zweite abstrakte test-Basisklasse definiert werden kann (D. H. EqualsOperatorsFixtureBase<T> : EqualsFixtureBase<T>), dass tests, die die Implementierung dieser Operatoren sind nicht nur korrekt, sondern auch im Einklang mit den erweiterten Definitionen von Equals() und GetHashCode().

Kann ich dies tun, mit NUnit, aber wenn mit MsTest ich Probleme.

a) nur Visual Studio 2010 entdeckt die Foo() test-Methode, nicht die geerbten Methoden testen, so kann er Sie nicht ausführen. Es scheint, die Visual Studio-test-loader nicht gehen die Vererbungshierarchie der test-Klasse.

b) Wenn ich diese Typen in TFS, TFS findet die abstrakte EqualsFixtureBase geben und denkt, es ist eine test-Klasse ausgeführt werden. Aber da es nicht erstellt werden kann, kann es nicht starten Sie es und Bezeichnungen der tests in dieser Art als nicht schlüssig -, die den test nicht ausführen, und so das bauen (!).

Gibt es eine Möglichkeit, dies zu umgehen, oder ist das eine Einschränkung von MsTest und Visual Studio?

Wenn dem so ist, ist die Festsetzung dieser in der roadmap für VS/TFS ??

Wäre dies sehr nützlich, vor allem beim testen von Produktionsarten, die eine Schnittstelle implementieren, oder sind Teil einer erbschaft hierarcy, wo bestimmte Mitglieder semantischen 'Vertragsart' Invarianten Eigenschaften oder - wenn das Sinn macht.

Grundsätzlich nicht mit Unterstützung für das hemmt mich von refactoring mein test-code zu entfernen Vervielfältigung.

Dank

EDIT: ich fand dieser link zu einem der MSDN-blogs, es sagt der folgende

"In Whidbey, Unterstützung für test-Klasse Vererbung fehlte. In Nunit, es wird vollständig unterstützt. Diese beseitigt werden Orcas".

Geschrieben wurde, vor über drei Jahren. Warum hat Sie diese nicht Hinzugefügt worden noch? Ich verstehe es nicht, es gibt berechtigte Gründe zu haben, dies und meiner Meinung nach wäre es eine kleine änderung. Oder bin ich nur nicht springen die rechten Reifen hier?

  • Jack & Rory: Die bounty-Periode geht zu Ende, während diese Frage bleibt weitgehend ungelöst, so dass ich nicht daneben, wie diese Frage beantwortet. Noch haben Sie dazu beigetragen, gut und beide teilweise geholfen, so habe ich gestimmt, bis jeder Ihrer Antworten einen slot. Wenn ich die Regeln verstehen, richtig dies bedeutet, Sie teilen die bounty-Punkte.
InformationsquelleAutor Mahol25 | 2010-08-19
Schreibe einen Kommentar