Unità Attacchi di prova WPF

voti
10

Sto cercando di unità di testare le mie DataBindings WPF utilizzando la prova costume fornito da Microsoft Team System. Mi piacerebbe essere in grado di testare le associazioni senza visualizzare la finestra perché la maggior parte dei miei test sarà per controlli utente e non in realtà su una finestra. Questo è possibile o c'è un modo migliore per farlo? Il seguente codice funziona se mostro la finestra, ma se non lo faccio, le associazioni non aggiornare.

            Window1_Accessor target = new Window1_Accessor();
            UnitTestingWPF.Window1_Accessor.Person p = new UnitTestingWPF.Window1_Accessor.Person() { FirstName = Shane };
            Window1 window = (target.Target as Window1);
            window.DataContext = p;         
            //window.Show(); //Only Works when I actually show the window
            //Is it possible to manually update the binding here, maybe?  Is there a better way?
            Assert.AreEqual(Shane, target.textBoxFirstName.Text);  //Fails if I don't Show() the window because the bindings aren't updated
È pubblicato 01/12/2008 alle 16:44
fonte dall'utente
In altre lingue...                            


5 risposte

voti
1

Bulbo oculare.
Questo tipo di markup dichiarativo rompe raramente .. a meno che qualcuno va in manuale e le viti in su. Anche allora, è possibile risolvere il problema in pochi minuti. IMHO il costo di scrivere tali prove superano di gran lunga i benefici.

Aggiornamento [Dec3,08]: Alrighty allora.
Il test è solo testando che la casella di testo ha il valore "FirstName", come la proprietà Path del legame. Se cambio / refactoring FirstName alla JustName nell'oggetto di origine dati effettivi, il test sarebbe ancora passare dal momento che è il test contro un tipo anonimo. (Test di verde quando il codice rotto - TDD antipattern: The Liar) Se il vostro scopo è quello di verificare che FirstName è stato specificato in XAML,

Assert.AreEqual("FirstName", txtBoxToProbe.GetBindingExpression(TextBox.TextProperty).ParentBinding.Path.Path);

Se davvero si deve prendere binding rotti tramite test di unità (e non si vuole mostrare l'interfaccia utente), utilizzare l'origine dati reali ... lottato per un po 'e si avvicinò con questo.

[Test]
public void TestTextBoxBinding()
{
   MyWindow w = new MyWindow();
   TextBox txtBoxToProbe = w.TextBox1;
   Object obDataSource = w;               // use 'real' data source 

   BindingExpression bindingExpr = BindingOperations.GetBindingExpression(txtBoxToProbe, TextBox.TextProperty);
   Binding newBind = new Binding(bindingExpr.ParentBinding.Path.Path);
   newBind.Source = obDataSource;
   txtBoxToProbe.SetBinding(TextBox.TextProperty, newBind);

   Assert.AreEqual("Go ahead. Change my value.", txtBoxToProbe.Text);
} 

Epilogo: C'è un po 'di vero e proprio roba occulta accadendo nella chiamata a Window.Show(). E 'in qualche modo imposta magicamente la proprietà DataItem dopo il quale inizia vincolanti dati di lavoro.

// before show
bindingExpr.DataItem => null
bindingExpr.Status => BindingStatus.Unattached

// after show
bindingExpr.DataItem => {Actual Data Source}
bindingExpr.Status => BindingStatus.Active

Una volta che l'associazione è attiva, credo che è possibile forzare gli aggiornamenti casella di testo tramite il codice come questo ..

txtBoxToProbe.GetBindingExpression(TextBox.TextProperty).UpdateTarget();

Ancora una volta, esprimo la mia riluttanza contro questo approccio. Ottenere NUnit per l'esecuzione in STA stato un dolore ..

Risposto il 01/12/2008 a 18:58
fonte dall'utente

voti
2

Shane, se quello che siete veramente preoccupa è un legame rottura in silenzio, si dovrebbe guardare a riorientare le tracce vincolanti da qualche parte è possibile esaminare. Mi piacerebbe iniziare qui:

http://blogs.msdn.com/mikehillberg/archive/2006/09/14/WpfTraceSources.aspx

Oltre a questo, sono d'accordo con Gishu che attacchi non sono buoni candidati per i test di unità, principalmente a causa della automagic in corso, che Gishu menzionato nel "Epilogo". Invece concentrarsi sul rendere che la classe sottostante si comporta correttamente.

Si noti, inoltre, che è possibile ottenere le tracce ancora più robusti che utilizzano la classe PresentationTraceSources:

http://msdn.microsoft.com/en-us/library/system.diagnostics.presentationtracesources.aspx

Spero possa aiutare!

Risposto il 03/12/2008 a 16:17
fonte dall'utente

voti
0

si può provare Guia . Con essa è possibile unità di testare la vostra UserControl e verificare se vincolanti i dati sono corretti. È necessario visualizzare la finestra però.

Ecco un esempio. Si avvia una nuova istanza del UserControl e ne imposta il DataContext e poi controlla se la casella di testo è impostato il giusto valore.

    [TestMethod]
    public void SimpleTest()
    {
        var viewModel = new SimpleControlViewModel() {TextBoxText = "Some Text"};

        customControl = CustomControl.Start<SimpleUserControl>((control) => control.DataContext = viewModel);

        Assert.AreEqual("Some Text", customControl.Get<TextBox>("textbox1").Value);

        customControl.Stop();
    }
Risposto il 04/11/2010 a 20:13
fonte dall'utente

voti
1

La combinazione di consigli mi sono imbattuto in una serie di messaggi SO che ho scritto la seguente classe che funziona molto bene per testare attacchi WPF.

public static class WpfBindingTester
{
    /// <summary>load a view in a hidden window and monitor it for binding errors</summary>
    /// <param name="view">a data-bound view to load and monitor for binding errors</param>
    public static void AssertBindings(object view)
    {
        using (InternalTraceListener listener = new InternalTraceListener())
        {
            ManualResetEventSlim mre = new ManualResetEventSlim(false);

            Window window = new Window
            {
                Width = 0,
                Height = 0,
                WindowStyle = WindowStyle.None,
                ShowInTaskbar = false,
                ShowActivated = false,
                Content = view
            };

            window.Loaded += (_, __) => mre.Set();
            window.Show();

            mre.Wait();

            window.Close();

            Assert.That(listener.ErrorMessages, Is.Empty, listener.ErrorMessages);
        }
    }

    /// <summary>Is the test running in an interactive session. Use with Assume.That(WpfBindingTester.IsAvailable) to make sure tests only run where they're able to</summary>
    public static bool IsAvailable { get { return Environment.UserInteractive && Process.GetCurrentProcess().SessionId != 0; } }


    private class InternalTraceListener : TraceListener
    {
        private readonly StringBuilder _errors = new StringBuilder();
        private readonly SourceLevels _originalLevel;
        public string ErrorMessages { get { return _errors.ToString(); } }

        static InternalTraceListener() { PresentationTraceSources.Refresh(); }

        public InternalTraceListener()
        {
            _originalLevel = PresentationTraceSources.DataBindingSource.Switch.Level;
            PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Error;
            PresentationTraceSources.DataBindingSource.Listeners.Add(this);
        }

        public override void Write(string message) {}

        public override void WriteLine(string message) { _errors.AppendLine(message); }

        protected override void Dispose(bool disposing)
        {
            PresentationTraceSources.DataBindingSource.Listeners.Remove(this);
            PresentationTraceSources.DataBindingSource.Switch.Level = _originalLevel;
            base.Dispose(disposing);
        }
    }
}
Risposto il 13/07/2012 a 10:16
fonte dall'utente

voti
4

Mentre alla ricerca di una soluzione per convertire WPF errori vincolanti in eccezione, ho capito che può essere utilizzato anche in un progetto di test di unità.

La tecnica è molto semplice:

  1. Derivare una TraceListenerche getta invece di registrazione
  2. Aggiungere che ascoltatore a PresentationTraceSources.DataBindingSource

Si prega di consultare la soluzione completa su GitHub , include un progetto di test di unità.

test fallito in Visual Studio

Risposto il 26/10/2013 a 19:45
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more