簡體   English   中英

與參數並行運行nunit測試(nunit 3.8.x)

[英]Run nunit tests parallel with parameters (nunit 3.8.x)

我想並行運行硒測試,並在assembly.cs中設置以下內容。

[assembly: Parallelizable(ParallelScope.Fixtures)]

好的。 這樣可行。

這是代碼結構的簡短示例

using NUnit.Framework;

namespace MyExample
{
    [TestFixture]
    [Category("TestsRunningWithLogin1")]
    public class Test_Example1
    {
        [Test, Order(1)]
        public void Test1()
        {
        }
        [Test, Order(2)]
        public void Test2()
        {
        }
    }

    [TestFixture]
    [Category("TestsRunningWithLogin2")]
    public class Test_Example2
    {
        [Test, Order(1)]
        public void Test1()
        {
        }
        [Test, Order(2)]
        public void Test2()
        {
        }
    }
}

測試需要用戶名和密碼,然后才能在網頁中進行操作。 當前在OneTimeSetUp方法中處理登錄等。 該網頁將最后使用的視圖保存在用戶設置中。

如果我按順序運行測試,那么我不會有問題,因為測試不會相互影響。 所有測試都可以使用相同的用戶名運行。

如果並行運行,它們可能會相互影響。 例如,test1配置了一個視圖,而在test2中不應看到。

我的想法是與不同的用戶一起運行這些類(其中有很多)。 測試開始時,它應該使用用戶名,並行運行測試當前未使用該用戶名。 目前,我不知道nunit正在並行運行哪些測試,因此無法直接對其進行參數化。

我沒有找到如何控制並行測試的任何東西。 我可以定義是否並行以及有多少並行執行。 我想要的是給並行運行測試參數。 如果我有3個並行運行的測試類,則要給出所有3個不同的參數。

有什么想法要實現嗎?

如何使用單例模式根據線程ID從一組密碼中進行分配。

快速說明

IThreadCredentials是一個描述憑證的接口,無論您的情況如何。

ThreadCredentials是我編寫的實現IThreadCredentials的簡單類。

ICredentialManager是一個界面,用於描述如何分配和返回憑據。

CredentialManager.Instance是在燈具之間共享的單例,以借用並返回憑證。

public interface IThreadCredentials
{
    string UserName { get; }

    string Password { get; }
}

public class ThreadCredentials : IThreadCredentials
{
    public ThreadCredentials(string userName, string password)
    {
        this.UserName = userName;
        this.Password = password;
    }

    public string UserName { get; }

    public string Password  { get; }
}

public interface ICredentialManager
{
    IThreadCredentials GetCredentialsFromPool();
    void ReturnCredentialsToPool();
}

public sealed class CredentialManager : ICredentialManager
{
    private static readonly Lazy<CredentialManager> lazy = new Lazy<CredentialManager>(() => new CredentialManager());
    private static readonly object syncRoot = new object ();
    private static readonly Queue<IThreadCredentials> availableCredentialQueue = new Queue<IThreadCredentials>();
    private static readonly IDictionary<int, IThreadCredentials> credentialsByThread = new Dictionary<int, IThreadCredentials>();

    private CredentialManager()
    {
        IEnumerable<IThreadCredentials> availableCredentials = new[]{new ThreadCredentials("Foo", "FooPassword"), new ThreadCredentials("Bar", "BarPassword")};
        foreach (IThreadCredentials availableCredential in availableCredentials)
        {
            availableCredentialQueue.Enqueue(availableCredential);
        }
    }

    public static CredentialManager Instance => lazy.Value;

    public IThreadCredentials GetCredentialsFromPool()
    {
        return GetCredentialsFromPool(Thread.CurrentThread.ManagedThreadId);
    }

    public void ReturnCredentialsToPool()
    {
        ReturnCredentialsToPool(Thread.CurrentThread.ManagedThreadId);
    }

    private static IThreadCredentials GetCredentialsFromPool(int threadId)
    {
        lock (syncRoot)
        {
            IThreadCredentials result;
            if (credentialsByThread.TryGetValue(threadId, out result))
            {
                return result;
            }

            // This presupposes you have enough credentials for the concurrency you are permitting 
            result = availableCredentialQueue.Dequeue();
            credentialsByThread.Add(threadId, result);
            return result;
        }
    }

    private static void ReturnCredentialsToPool(int threadId)
    {
        lock (syncRoot)
        {
            if (credentialsByThread.ContainsKey(threadId))
            {
                IThreadCredentials credentials = credentialsByThread[threadId];
                credentialsByThread.Remove(threadId);
                availableCredentialQueue.Enqueue(credentials);
            }
        }
    }
}

用法:

在測試夾具設置中,您可以執行以下操作:

IThreadCredentials credentials = CredentialManager.Instance.GetCredentialsFromPool();
// Now you can use credentials for whatever

在拆解中,您可以

CredentialManager.Instance.ReturnCredentialsToPool();
// Then promise you stop using those credentials

顯然,在並行運行線程時,您將需要至少具有可用憑據的數量,否則出隊會出現異常。

使用nunit TestCase(“ data”)屬性示例:

 [TestCase("differentUserName", "password")]
 public void MyTest(string username, string password)          
 {  
   // Test steps
  }

如果沒有nunit,可能的答案是提供參數的一點服務。 因此,每個並行測試都應調用一個Web服務,並將獲得其唯一的參數。 每次調用時,Web服務將返回下一個參數集。

如果我提供10個不同的參數集並並行運行3個測試,我可以肯定的是,這3個並行測試永遠不會獲得相同的參數。 假設所有測試用例幾乎都需要相同的時間。

我會稱其為hack,因此我需要一個nunit解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM