如何自动化测试中等信任代码
Posted
技术标签:
【中文标题】如何自动化测试中等信任代码【英文标题】:How to Automate Testing of Medium Trust Code 【发布时间】:2010-11-02 12:10:01 【问题描述】:我想编写以中等信任度运行的自动化测试,如果需要完全信任则失败。
我正在编写一个库,其中某些功能仅在完全信任的情况下可用,我想验证我希望在中等信任下运行的代码是否可以正常工作。如果还想知道如果我更改需要完全信任的类,我的测试将失败。
我已尝试创建另一个 AppDomain 并加载中等信任 PolicyLevel,但在尝试运行跨 AppDomain 回调时,我总是遇到程序集错误或无法加载其依赖项。
有没有办法解决这个问题?
更新:基于回复,这就是我所拥有的。请注意,您正在测试的类必须扩展 MarshalByRefObject。这是非常有限的,但我看不出有什么办法。
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using Xunit;
namespace PartialTrustTest
[Serializable]
public class ClassUnderTest : MarshalByRefObject
public void PartialTrustSuccess()
Console.WriteLine( "partial trust success #1" );
public void PartialTrustFailure()
FieldInfo fi = typeof (Int32).GetField( "m_value", BindingFlags.Instance | BindingFlags.NonPublic );
object value = fi.GetValue( 1 );
Console.WriteLine( "value: 0", value );
public class Test
[Fact]
public void MediumTrustWithExternalClass()
// ClassUnderTest must extend MarshalByRefObject
var classUnderTest = MediumTrustContext.Create<ClassUnderTest>();
classUnderTest.PartialTrustSuccess();
Assert.Throws<FieldAccessException>( classUnderTest.PartialTrustFailure );
internal static class MediumTrustContext
public static T Create<T>()
AppDomain appDomain = CreatePartialTrustDomain();
var t = (T) appDomain.CreateInstanceAndUnwrap( typeof (T).Assembly.FullName, typeof (T).FullName );
return t;
public static AppDomain CreatePartialTrustDomain()
var setup = new AppDomainSetup ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
var permissions = new PermissionSet( null );
permissions.AddPermission( new SecurityPermission( SecurityPermissionFlag.Execution ) );
permissions.AddPermission( new ReflectionPermission( ReflectionPermissionFlag.RestrictedMemberAccess ) );
return AppDomain.CreateDomain( "Partial Trust AppDomain: " + DateTime.Now.Ticks, null, setup, permissions );
【问题讨论】:
【参考方案1】:无耻地从How to Host a Partial Trust Sandbox – #7 窃取,但在 F# 中重新实现(连同一个简单的测试用例)只是为了好玩:-)
open System
open System.Reflection
open System.Security
open System.Security.Permissions
open System.Security.Policy
type Program() =
inherit System.MarshalByRefObject()
member x.PartialTrustSuccess() =
Console.WriteLine("foo")
member x.PartialTrustFailure() =
let field = typeof<Int32>.GetField("m_value", BindingFlags.Instance ||| BindingFlags.NonPublic)
let value = field.GetValue(1)
Console.WriteLine("value: 0", value)
[<EntryPoint>]
let main _ =
let appDomain =
let setup = AppDomainSetup(ApplicationBase = AppDomain.CurrentDomain.BaseDirectory)
let permissions = PermissionSet(null)
permissions.AddPermission(SecurityPermission(SecurityPermissionFlag.Execution)) |> ignore
permissions.AddPermission(ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)) |> ignore
AppDomain.CreateDomain("Partial Trust AppDomain", null, setup, permissions)
let program = appDomain.CreateInstanceAndUnwrap(
typeof<Program>.Assembly.FullName,
typeof<Program>.FullName) :?> Program
program.PartialTrustSuccess()
try
program.PartialTrustFailure()
Console.Error.WriteLine("partial trust test failed")
with
| :? FieldAccessException -> ()
0
还有一个 C# 版本:
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
namespace PartialTrustTest
internal class Program : MarshalByRefObject
public void PartialTrustSuccess()
Console.WriteLine("partial trust success #1");
public void PartialTrustFailure()
FieldInfo fi = typeof(Int32).GetField("m_value", BindingFlags.Instance | BindingFlags.NonPublic);
object value = fi.GetValue(1);
Console.WriteLine("value: 0", value);
private static AppDomain CreatePartialTrustDomain()
AppDomainSetup setup = new AppDomainSetup() ApplicationBase = AppDomain.CurrentDomain.BaseDirectory ;
PermissionSet permissions = new PermissionSet(null);
permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
permissions.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess));
return AppDomain.CreateDomain("Partial Trust AppDomain", null, setup, permissions);
static void Main(string[] args)
AppDomain appDomain = CreatePartialTrustDomain();
Program program = (Program)appDomain.CreateInstanceAndUnwrap(
typeof(Program).Assembly.FullName,
typeof(Program).FullName);
program.PartialTrustSuccess();
try
program.PartialTrustFailure();
Console.Error.WriteLine("!!! partial trust test failed");
catch (FieldAccessException)
Console.WriteLine("partial trust success #2");
C:\temp\PartialTrustTest\bin\Debug>PartialTrustTest.exe
部分信任成功 #1
部分信任成功 #2
【讨论】:
尝试了一段时间,无法根据您的代码或源材料进行工作单元测试。您是否成功地将其放入 c# 单元测试并让测试适当地通过和失败?【参考方案2】:我刚刚发布了一篇标题为Partial Trust Testing with xUnit.net 的文章。它详细介绍了我们在 Entity Framework 团队中使用的基于 xUnit.net 的框架,以在部分信任下运行代码。
这是一个使用示例。
public class SomeTests : MarshalByRefObject
[PartialTrustFact]
public void Partial_trust_test1()
// Runs in medium trust
// Or...
[PartialTrustFixture]
public class MoreTests : MarshalByRefObject
[Fact]
public void Another_partial_trust_test()
// Runs in medium trust
【讨论】:
问题是您的代码不再适用于 xUnit 的最新版本...他们在 1.9 和 2.0 之间甚至在 2.0 和 2.1 之间更改了 API 太大...【参考方案3】:我已经发布了一篇关于 Medium Trust 单元测试的三部分博文
我以与此处的某些答案类似的方式启动了一个替代 AppDomain,但通过使用 MarshalByRefObject 来调用另一个 AppDomain 中的测试方法,这意味着您的测试类不需要实现 MarshalByRefObject
第三部分(包含其他部分的链接)在这里http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with-nunitpart-three-umbraco-framework-testing/
【讨论】:
我还应该指出,在帖子中是一个可下载的基类,您可以将其用于任何 NUnit 夹具 那个链接好像失效了——你有文章的新家吗?【参考方案4】:我从未尝试过这样做,但一般来说,要处理来自自定义 AppDomain 的程序集加载失败,您可以使用 AppDomain.AssemblyResolve 事件。
虽然完全不相关,但这里是an example of using AppDomain.AssemblyResolve。
【讨论】:
【参考方案5】:答案取决于当具有中等信任权限的人尝试访问完全信任功能时,您的代码会做什么。我假设会抛出某种异常。
在这种情况下,编写一个在中等信任上下文中运行的单元测试,尝试访问完全信任的特性,并期望抛出异常。如果您从未编写过这样的测试,那么大多数测试框架都支持的一种常见方法是:
testMediumTrustUserWontAccessFeatureX()
// set up the context of your test ...
try
accessFullTrustFeature();
fail("Test failed - Medium trust user can access full trust feature");
catch( SomeKindOfException e )
// Success - feature was denied to the untrusted user
如果捕获到异常,则意味着您的不受信任的用户无法访问该功能(并且测试通过),但如果从未捕获到异常,则测试失败(我们预期会出现异常但没有得到它)。
这是 java 风格的伪代码,但假设它支持异常处理,该模式应该适用于您使用的任何语言。
【讨论】:
是的,我希望在运行需要完全信任的代码时会抛出异常。我无法实现测试的“//设置您的测试的上下文......”部分来为代码运行建立一个中等信任上下文。我已经编写了一个库,我想验证一下它的所有例程都将在中等信任环境中成功运行。以上是关于如何自动化测试中等信任代码的主要内容,如果未能解决你的问题,请参考以下文章