艾伟:为WPF项目创建单元测试

简介: 可能你已发现一个问题,我们无法使用VS对WPF项目创建单元测试(VS2005不行,VS2008我没试过,但据说也不行),这让人很郁闷,这里将介绍如何使用NUnit来对WPF项目创建单元测试并解决其中的难题(但利用NUnit来对WPF创建单元测试时并不会像针对.

可能你已发现一个问题,我们无法使用VS对WPF项目创建单元测试(VS2005不行,VS2008我没试过,但据说也不行),这让人很郁闷,这里将介绍如何使用NUnit来对WPF项目创建单元测试并解决其中的难题(但利用NUnit来对WPF创建单元测试时并不会像针对.Net2.0一样容易,可能会出现一些小问题).

1,对普通类(非WPF UI组件)进行测试:
 这和在.Net2.0中使用NUnit进行测试时一样,不会出现任何问题,参考下面的代码:

    [TestFixture]
    
public   class  ClassTest
    
{
        [Test]
        
public void TestRun()
        
{
            ClassLibrary1.Class1 obj 
= new ClassLibrary1.Class1();

            
double expected = 9;
            
double result = obj.GetSomeValue(3);

            Assert.AreEqual(expected, result);
        }

     }


2,对WPF UI组件进行测试
 使用NUnit对WPF UI组件(比如MyWindow,MyUserControl)进行测试的时候,NUnit会报如下异常:“The calling thread must be STA, because many UI components require this”。
下面是错误的测试代码:

[TestFixture]
    
public   class  ClassTest
    
{
        [Test]
        
public void TestRun()
        
{
            WindowsApplication1.Window1 obj 
= new WindowsApplication1.Window1();

            
double expected = 9;
            
double result = obj.GetSomeValue(3);

            Assert.AreEqual(expected, result);
        }

     }

wpfUnitTestError1.png


为了让调用线程为STA,我们可以编写一个辅助类CrossThreadTestRunner:

using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Threading;
using  System.Security.Permissions;
using  System.Reflection;

namespace  TestUnit
{
    
public class CrossThreadTestRunner
    
{
        
private Exception lastException;

        
public void RunInMTA(ThreadStart userDelegate)
        
{
            Run(userDelegate, ApartmentState.MTA);
        }


        
public void RunInSTA(ThreadStart userDelegate)
        
{
            Run(userDelegate, ApartmentState.STA);
        }


        
private void Run(ThreadStart userDelegate, ApartmentState apartmentState)
        
{
            lastException 
= null;

            Thread thread 
= new Thread(
              
delegate()
              
{
                  
try
                  
{
                      userDelegate.Invoke();
                  }

                  
catch (Exception e)
                  
{
                      lastException 
= e;
                  }

              }
);
            thread.SetApartmentState(apartmentState);

            thread.Start();
            thread.Join();

            
if (ExceptionWasThrown())
                ThrowExceptionPreservingStack(lastException);
        }


        
private bool ExceptionWasThrown()
        
{
            
return lastException != null;
        }


        [ReflectionPermission(SecurityAction.Demand)]
        
private static void ThrowExceptionPreservingStack(Exception exception)
        
{
            FieldInfo remoteStackTraceString 
= typeof(Exception).GetField(
              
"_remoteStackTraceString",
              BindingFlags.Instance 
| BindingFlags.NonPublic);
            remoteStackTraceString.SetValue(exception, exception.StackTrace 
+ Environment.NewLine);
            
throw exception;
        }

    }

}

并编写正确的测试代码:

    [TestFixture]
    
public   class  ClassTest
    
{
        [Test]
        
public void TestRun()
        
{
            
            CrossThreadTestRunner runner 
= new CrossThreadTestRunner();
            runner.RunInSTA(
              
delegate
              
{
                  Console.WriteLine(Thread.CurrentThread.GetApartmentState());

                  WindowsApplication1.Window1 obj 
= new WindowsApplication1.Window1();

                  
double expected = 9;
                  
double result = obj.GetSomeValue(3);
                  Assert.AreEqual(expected, result);
              }
);   

        }

  }



wpfUnitTestOK.png

另外,使用NUnit时,您需要添加对nunit.framework.dll的引用,并对测试类添加[TestFixture]属性标记以及对测试方法添加[Test]属性标记,然后将生成的程序集用nunit.exe打开就可以了,关于NUnit的具体用法您可以参考其官方文档。

目录
相关文章
|
2月前
|
监控 JavaScript 前端开发
在生产环境中测试和监控Vue项目的方法有哪些?
在生产环境中测试和监控Vue项目的方法有哪些?
28 4
|
4月前
|
监控 安全 测试技术
从开发到测试再到发布,全方位解析项目上线的完美路程!
从开发到测试再到发布,全方位解析项目上线的完美路程!
126 0
|
6月前
|
网络协议 安全 Linux
12. 测试搭建百万并发项目
12. 测试搭建百万并发项目
74 0
|
6月前
|
JavaScript 测试技术 API
vue項目加入单元测试模块,使用jest
vue項目加入单元测试模块,使用jest
61 0
|
5月前
|
移动开发 前端开发 JavaScript
VSCode设置类似Webstorm那样可以用本地局域网IP地址访问自己开发的测试项目,vs code 前端如何以服务器模式打开?
VSCode设置类似Webstorm那样可以用本地局域网IP地址访问自己开发的测试项目,vs code 前端如何以服务器模式打开?
VSCode设置类似Webstorm那样可以用本地局域网IP地址访问自己开发的测试项目,vs code 前端如何以服务器模式打开?
|
4月前
|
存储 Rust 测试技术
【一起学Rust · 项目实战】命令行IO项目minigrep——测试驱动开发完善功能
【一起学Rust · 项目实战】命令行IO项目minigrep——测试驱动开发完善功能
98 0
|
2天前
|
XML Java 测试技术
Maven 构建 & 项目测试
本文介绍了如何使用Maven构建和测试Java应用。在`C:/MVN/consumerBanking`项目中,`pom.xml`配置了JUnit作为测试框架。执行`mvn clean package`命令进行构建,Maven会清理目标目录,编译源码和测试代码,运行测试用例,最后生成`consumerBanking-1.0-SNAPSHOT.jar`。测试报告位于`surefire-reports`文件夹。添加新Java类`Util.java`到项目后,更新`App.java`以使用`Util`类。
|
8天前
|
测试技术
使用CLion创建Cmake项目,使用GoogleTest和GoogleMock对代码进行测试
使用CLion创建Cmake项目,使用GoogleTest和GoogleMock对代码进行测试
20 3
|
9天前
|
XML Java 测试技术
Maven 构建 & 项目测试
该文介绍了如何使用Maven进行Java应用的构建与测试。在`C:/MVN/consumerBanking`项目中,`pom.xml`配置了JUnit依赖。Maven默认创建了源码和测试文件,通过命令`mvn clean package`进行构建,生成`consumerBanking-1.0-SNAPSHOT.jar`。测试报告在`surefire-reports`文件夹。新增`Util`类并更新`App`后,执行`mvn clean compile`编译,然后运行`java -cp . com.companyname.bank.App`显示"Hello World!"。
|
12天前
|
机器学习/深度学习 算法 UED
【Python 机器学习专栏】A/B 测试在机器学习项目中的应用
【4月更文挑战第30天】A/B测试在数据驱动的机器学习项目中扮演关键角色,用于评估模型性能、算法改进和特征选择。通过定义目标、划分群组、实施处理、收集数据和分析结果,A/B测试能帮助优化模型和用户体验。Python提供工具如pandas和scipy.stats支持实验实施与分析。注意样本量、随机性、时间因素和多变量分析,确保测试有效性。A/B测试助力于持续改进机器学习项目,实现更好的成果。

热门文章

最新文章