我們使用WatiN測試了我們想要在CruiseControl.NET服務器上運行的測試。我們已經完成了一個單一的構建。當我們在其他版本中啓用這些測試時,它們在同時運行時會失敗。我們希望避免將所有運行這些測試的構建放在同一個cc.net隊列中,因爲這些測試只是整個構建時間的一小部分。我們還希望避免爲這些測試分開構建項目,因爲這會使cc.net安裝中的構建量翻番。在單個CruiseControl.NET服務器上使用WatiN測試運行並行構建
我們有什麼選擇?
- 是否有任何方法可以將這些測試放入自己的cc.net任務中,並將該任務放在隊列中?
- 是否有任何msbuild/nant/ccnet任務或任何處理排隊?
- 是否有任何命令行工具可以從我們的msbuild腳本運行來處理命令行任務的排隊,以便我們可以使用nunit命令行調用運行我們的測試?
- 是否有任何其他智能解決方案來解決這個問題?
如果我們沒有找到任何現有的解決方案來解決這個問題,我們可能會自己建立一些東西,如果是的話,哪個解決方案會被推薦?
編輯: 這是我最後執行互斥:
public class SystemLevelLock : IDisposable
{
private readonly string _id;
private bool _isAquired;
private Mutex _mutex;
public SystemLevelLock(string id)
{
_id = id;
Aquire();
}
public SystemLevelLock() : this(GetApplicationId()) { }
private void Aquire()
{
try
{
var mutex = GetMutex();
_isAquired = mutex.WaitOne(TimeSpan.FromMinutes(1), false);
if (!_isAquired)
throw new Exception("System level mutex could not be aquired");
}
catch (AbandonedMutexException)
{
// Mutex was abandoned by another process (it probably crashed)
// Mutex was aquired by this process instead
}
}
private Mutex GetMutex() { return _mutex ?? (_mutex = MakeMutex()); }
private Mutex MakeMutex()
{
var mutexId = string.Format("Global\\{{{0}}}", _id);
var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(allowEveryoneRule);
var mutex = new Mutex(false, mutexId);
mutex.SetAccessControl(securitySettings);
return mutex;
}
private void Release()
{
if (_isAquired)
_mutex.ReleaseMutex();
}
public void Dispose() { Release(); }
}
這是使用互斥瀏覽器類的實現。這也使用SpecFlow scenariocontext來存儲瀏覽器實例併爲此場景鎖定。
public static class Browser
{
public static IE Current
{
get
{
if (!IsStarted())
Start();
return ScenarioBrowser;
}
}
private static IE ScenarioBrowser
{
get
{
if (ScenarioContext.Current.ContainsKey("browser"))
return ScenarioContext.Current["browser"] as IE;
return null;
}
set
{
if (value == null)
{
if (ScenarioContext.Current.ContainsKey("browser"))
ScenarioContext.Current.Remove("browser");
}
else
ScenarioContext.Current["browser"] = value;
}
}
private static IDisposable BrowserLock
{
get
{
if (ScenarioContext.Current.ContainsKey("browserLock"))
return ScenarioContext.Current["browserLock"] as IDisposable;
return null;
}
set
{
if (value == null)
{
if (ScenarioContext.Current.ContainsKey("browserLock"))
ScenarioContext.Current.Remove("browserLock");
}
else
ScenarioContext.Current["browserLock"] = value;
}
}
private static void LockBrowser()
{
BrowserLock = MakeBrowserLock();
}
private static void ReleaseBrowser()
{
BrowserLock.Dispose();
BrowserLock = null;
}
private static SystemLevelLock MakeBrowserLock() { return new SystemLevelLock("WatiNBrowserLock"); }
private static void Start()
{
LockBrowser();
var browser = new IE();
ScenarioBrowser = browser;
}
public static bool IsStarted() { return ScenarioBrowser != null; }
public static void Close()
{
try
{
var browser = ScenarioBrowser;
ScenarioBrowser = null;
browser.Close();
browser.Dispose();
}
finally
{
ReleaseBrowser();
}
}
}
請將解決方案添加到您自己的問題中,而不是答案。 –
有人說編輯答案,一些編輯問題=) – MatteS
我更喜歡常識..這是你的問題。如果完整的解決方案是由答案中的其他人提供的,所以它很好。但是,如果您是最終解決方案的參與者,那麼您可以期望它在原始問題中顯示爲後續內容,或者由您單獨回答。 –