1. 程式人生 > >.netcore持續整合測試篇之web專案驗收測試

.netcore持續整合測試篇之web專案驗收測試

系列目錄

通過前面的單元測試,我們能夠保證專案的基本模組功能邏輯是正常的,通過整合測試能夠保證介面的請求是正常的.然而最終專案交付我們還需要對專案進行頁面的行為進行測試,比如頁面佈局是否正常,按鈕是否能點選,點選後執行的動作是否正確,連結是否正常等功能進行測試,表單提交是否返回正確結果等.這些都是一些墨盒測試,一般是由專門測試人員來完成,然而隨著web的發展,各種自動化工具越來越完善,有一些頁面功能的測試也可以由程式設計師來編寫自動測試程式碼完成.這裡主要結合Selenium來介紹如何完成頁面行為的測試.

點選按鈕

前面我們已經講到如何安裝和簡單使用Selenium,這裡不再介紹.下面介紹一下如何使用Selenium來觸發一個按鈕點選事件.

首先我們在HelloWorldController裡新建Action FormTest(也可以在其它控制器裡建立,這裡隨意),程式碼如下

 public IActionResult FormTest()
        {
            return View();
        }
        [HttpPost]
        public IActionResult FormTest(string name)
        {
            return Content(name);
        }

以上程式碼非常簡單,我們建立FormTest並請求自己,然後把請求的資料返回

我們為這個Action新建一個頁面,並且引入jquery.

頁面程式碼如下

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <script src="~/js/JQueryt.js"></script>
    <title>FormTest</title>
</head>
<body>
<form method="post" id="frm1">
    <input id="btn1" type="button" value="點我"/>
</form>
<script>
    $("#btn1").click(function() {
        alert("hello,world");
    });
</script>
</body>
</html>

這個頁面裡有一個btn1,如果我們點選它就會彈出一個alert框.
測試程式碼如下

        [Fact]
        public void ClickTest()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);

            driver.Url = "http://localhost:28614/HelloWorld/FormTest";
            driver.Navigate();
            var element = driver.FindElement(By.Id("btn1"));
            element.Click();
        }

我們先通過id找到這個按鈕,然後令它觸發一個click事件.我們執行測試

我們並沒有手動點選按鈕,但是彈出了上面的彈框,說明點選事件正確觸發了.

自動填寫表單

通過以上程式碼我們可以看到,觸發一個按鈕點選事件在Selenium是非常容易的,這對我們自動模擬表單提交提供了大大的便利.Selenium還可以模擬自動填寫表單,思路和上面是一樣的,首先獲取到要填寫的表單,然後模擬填寫內容.下面我們改動一下網頁程式碼,在form裡面新增一個簡單的表單

<input type="text" name="name"/>

測試程式碼改為如下:

       [Fact]
        public void ClickTest()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);

            driver.Url = "http://localhost:28614/HelloWorld/FormTest";
            driver.Navigate();
            var input = driver.FindElement(By.Name("name"));
            input.SendKeys("hello,world");
        }

以上代通過FindElement By.Name獲取到頁面裡name為name的元素(聽起來有點繞),然後通過SendKeys方法模擬向指定元素填寫內容

頁面的開以後便會自動填寫以上內容.這樣我們就可以自動填寫內容,然後點選點我按鈕提交表單了.

自動填寫表單,然後提交

綜合以上我們模擬一次自動填寫表單,然後提交的動作.

下面貼出修改後的完整程式碼.

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <script src="~/js/JQueryt.js"></script>
    <title>FormTest</title>
</head>
<body>
<form method="post" id="frm1">
    <input type="text" name="name"/>
    <input id="btn1" type="button" value="點我"/>
</form>
<script>
    $("#btn1").click(function() {
        $.ajax({
            type: "POST",
            url: "/HelloWorld/FormTest",
            data: $("#frm1").serialize(),
            dataType: "text",
            success: function (response) {
                alert("返回的資料是:"+response);
            }
        });
    });
</script>
</body>
</html>

這次當按鈕點選以後我們觸發一次ajax提交,然後alert伺服器返回的資料

測試程式碼如下:

        [Fact]
        public void ClickTest()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);

            driver.Url = "http://localhost:28614/HelloWorld/FormTest";
            driver.Navigate();
            var input = driver.FindElement(By.Name("name"));
            input.SendKeys("hello,world");
            var btn = driver.FindElement(By.Id("btn1"));
            btn.Click();
        }

上面的程式碼執行了兩個動作,第一是模擬填寫表單資料,第二是點選按鈕,提交表單.
我們執行測試程式碼,看一下結果

可以看到表單自動提交了.

獲取Alert框

我們前面都是通過截圖來看指定的行為是否產生了正確的結果,然而在自動化環境中這是不能接受的,更多的時候我們是在無頭模式下進行測試,然後自動獲取行為產生的結果,然後斷言此結果是否是期待的一個值.下面我們改造以上程式碼,自動獲致到Alert框並取得它裡面的值,然後斷言這個值是我們想要的值.

 [Fact]
        public void ClickTest()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);

            driver.Url = "http://localhost:28614/HelloWorld/FormTest";
            driver.Navigate();
            var input = driver.FindElement(By.Name("name"));
            input.SendKeys("hello,world");
            var btn = driver.FindElement(By.Id("btn1"));
            btn.Click();
            Thread.Sleep(3000);
            var alert = driver.SwitchTo().Alert();
            var txt = alert.Text;
            Assert.Equal("返回的資料是:hello,world", txt);
        }

以上程式碼的關鍵是通過SwitchTo獲取到Alert框,進而獲取到它的Text值,我們在ajax請求成功的處理是"返回的資料是:"+提交的值,因此如果正常則以上程式碼會執行成功.這樣我們就不用守著頁面檢視結果了.

獲取自定義彈出層

做到以上並沒有成事大吉,實際業務中我們很少使用瀏覽器自帶的Alert,而是使用一些第三方的元件,因為原生Alert使用者體驗實在不是太好,只能在測試的時候玩一玩還可以.由於第三方元件實現方式不同,這就導致獲取的方法也不一樣,我們還要根據具體情況而定.下面我們結合layui的alert框來介紹一下如何來獲取它裡面的內容.

我們在專案中引入layui,然後把ajax請求成功後的alert換成layui的alert,程式碼如下

<html>
<head>
    <meta name="viewport" content="width=device-width" />

    <link href="~/lib/layui/css/layui.css" rel="stylesheet" />
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/layui/layui.all.js"></script>
    <title>FormTest</title>
</head>
<body>
<form method="post" id="frm1">
    <input type="text" name="name"/>
    <input id="btn1" type="button" value="點我"/>
</form>
<script>
    var layer = layui.layer;
    $("#btn1").click(function() {
        $.ajax({
            type: "POST",
            url: "/HelloWorld/FormTest",
            data: $("#frm1").serialize(),
            dataType: "text",
            success: function (response) {
                layer.alert("返回的資料是:" + response);
            }
        });
    });
</script>
</body>
</html>

由於這是一個自定義alert,我們先執行一下專案,然後手動點選下按鈕,等alert框出來以後我們分析一下它的結構:

我們可以看到,layui的這個alert框實際上是一個div層,由於id是動態生成的,因此我們不能使用,但是它的class是固定的,它包含了兩個class元素,內部彈出的具體內容則是藍色高亮的那個div裡面的內容,它的class也是固定的,我們這裡可以使用class獲取到它們.

下面看測試程式碼:

       [Fact]
        public void ClickTest()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);

            driver.Url = "http://localhost:28614/HelloWorld/FormTest";
            driver.Navigate();
            var input = driver.FindElement(By.Name("name"));
            input.SendKeys("hello,world");
            var btn = driver.FindElement(By.Id("btn1"));
            btn.Click();
            Thread.Sleep(3000);
            var layer = driver.FindElement(By.ClassName("layui-layer-dialog"));
            var content = layer.FindElement(By.ClassName("layui-layer-content"));
            var text = content.Text;
            Assert.Equal("返回的資料是:hello,world", text);
        }

產生我們通過class獲取到這個彈出層元素,然後再通過它找到它的子元素(包含彈出資訊文字的div).這裡的sleep前面說過,由於js是非同步執行的,因此點選後並不能馬上獲取到結果,這裡我們sleep一下.

需要特別注意的是,通過By.ClassName獲取到的元素可能不止一下,預設取得的是獲取到的第一個,這在有些時候可能並不能滿足我們的要求(這裡程式碼比較少,發生衝突的機率比較小),實際工作中我們一定要想辦法保證元素的惟一性,也就是獲取到的元素確定是我們所需要的.

還有一點需要注意的是第三方的元件實現方式可能會改變導致獲取不到內容,這確實沒有比較好的解決方案.

實際工作中可能還會有更為複雜的行為要去模擬,比如說彈出層是一個帶有tab的面板,我們需要切換到特定的tab去尋找想要的內容,由於這些內容都是非標準實現,因此模擬的難度根據採用框架的複雜度而定,有時候可能特別複雜,但是隻要靜下心來分析分析,總是能找到解決方案的.

前面講到了如何填寫表單,點選按鈕提交表單以及獲取彈出層內容.下面講解一下如何獲取連結,彈出頁面,iframe以及高階行為.這裡仍然是以實際應該為主導講解一些最基本最常用的功能,並不求面面俱到,有興趣的同事可以檢視官方文件,第三方部落格,書籍等獲取更多知識.

連結行為測試

連結很多時候可以完成按鈕的功能,但是最常用的是跳到一個新的頁面,下面講一下如何獲取到新的頁面

我們在上節的頁面中新增一個a連結,程式碼如下:

<a id="clk" href="http://www.baidu.com" target="_blank">飛往百度</a>

以上程式碼很簡單,點選一下a標籤就會出現一個新的百度頁面,我們想要判斷一下是否正確打開了百度頁面,測試程式碼如下:

        [Fact]
        public void LinkClick()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);

            driver.Url = "http://localhost:28614/HelloWorld/FormTest";
            driver.Navigate();
            var link = driver.FindElement(By.Id("clk"));
            link.Click();
            var hands = driver.WindowHandles;
            var wind = driver.SwitchTo().Window(hands[1]);
            var title = wind.Title;
            Assert.Equal("百度一下,你就知道", title);
        }

上面程式碼主要的功能在於當點選連結以後通過driver.WindowHandles獲取到容器的控制代碼,需要說明的是這裡的控制代碼並不是指標型別的控制代碼,而是一個字串類型別的變數,我們可以通過它找到指定的視窗,下面部分通過SwitchTo切換到一個視窗(SwitchTo我們前面講到過),Window接收一個字串類開的引數,雖然提示字元說是視窗的標題,實際上並不是,而是我們剛才獲取到的控制代碼,我們知道現在共有兩個視窗,百度視窗是後開啟的,因此它的索引是是1.然後我們再獲取它的標題,看看是不是"百度一下, 你就知道"

需要說明的是,以上我們雖然是通過索引獲取的百度視窗,這樣可能會因為位置切換造成問題(這裡強烈不建議手動修改自動過程中的行為,實際上真實的測試環境是無頭環境,因此這其實不是一個很大的問題),就上面的例子我們確實有辦法能惟一確定百度視窗,但是如果視窗過多想要不使用索引獲取到指定的視窗還是很困難的,這裡強烈建議如果有開啟非常多的視窗的複雜行為時,把測試分成若干個測試,每個測試裡的邏輯只打開少量視窗,這樣出現問題也更容易排查.

點選時按下修改鍵

前面我們多次用到了模擬點選事件,其實這也是實際專案中用的最多的,但是也不排除少數情況下會用到其它的按鍵,比如說拖拽,雙擊,ctrl+點選等,

下面我們演示如何在百度首頁點選百度新聞並在新頁面開啟,我們知道百度首頁的新聞預設是在本頁開啟的,如果點選連結時按下ctrl鍵則會在新頁面中開啟.下面我們模擬ctrl+點選這個行為
這裡其實也很簡單,主要通過Actions封裝物件來觸發一系列動作來達到我們的目的.

下面看測試程式碼:

       [Fact]
        public void LinkClick()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);

            driver.Url = "http://www.baidu.com";
            driver.Navigate();
            var link = driver.FindElement(By.LinkText("新聞"));
            Actions actions = new Actions(driver);
            actions.KeyDown(Keys.LeftControl).Click(link).Build().Perform();
        }

以上程式碼主要是通過傳入driver物件構造一個Actions型別物件,這個物件在呼叫build之前會一直返回自身,類似是是jQuery裡的鏈式操作,這樣我們就可以連續執行多個動作.

下面的程式碼我們先是呼叫actions物件的keyDown方法,然後傳入要按下的鍵,然後再呼叫點選事件,最後呼叫Build方法終止鏈式呼叫,最後再執行Perform執行前面的操作.啟動測試就會發現瀏覽器在新的頁面打開了百度新聞頁

上面用到了一個以前沒用到的選擇方法那就是By.LinkText,語義非常明確那就是根據連結的文字找到連結物件.

Iframe物件的獲取

我們知道Iframe物件的處理比較麻煩,裡面是一個比較封裝的區域與外面通訊過程比較麻煩,在selenium裡它的處理也比較特殊,直接按照id或者其它特徵獲取到它幾乎沒有任何作用,因為無法獲取到內容元素,selenium是通過switchTo.Frame傳入獲取到的iframe物件對它進行一層封裝,然後就能夠正常獲取到它內部的元素了.

我們在頁面新增一個簡單的iframe頁面,程式碼如下

<iframe id="ifrm1" src="http://www.baidu.com"></iframe>

測試程式碼如下

        [Fact]
        public void FindIframe()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);
            driver.Url = "http://localhost:28614/HelloWorld/FormTest";
            driver.Navigate();
            var ele = driver.FindElement(By.Id("ifrm1"));
            var frm = driver.SwitchTo().Frame(ele);
            var txt = frm.FindElement(By.LinkText("新聞")).Text;
            Assert.Equal("新聞", txt);
        }

以上程式碼首先像獲取普通元素一樣獲取到這個iframe物件,然後通過SwitchTo.Frame把它傳入封裝成個frame物件,後面就可以獲取到它內部的元素了.(iframe指向百度首頁,我們獲取到新聞連結)

然而實際專案中,往往我們並不自己去建立iframe,而是由一些第三方ui框架自動建立的,框架生成的iframe要麼沒有id,要麼是動態的,因此使用自動生成元素的id要非常慎重,但是筆者見過不少在生成iframe時可以給iframe指定name的,由於頁面中iframe一般都不會太多,我們可以給它命一個惟一的名字,通過名字找到它.如果沒有名字,還可以根據它的class找到它,一般iframe樣式class都是固定的,但是這時候要想辦法確保選擇到的物件是惟一的,這樣才能保證測試結果的穩定性.

獲取下拉列表

在一些查詢功能中,往往全有下拉列表,通過js獲取或者設定下拉項並不是一件很困難的事,然而我們並不想不了測試而增加無關的js程式碼,這樣用完還要刪除非常麻煩,其實Selenium也提供了設定下拉列表選項的功能,這樣極大方便了我們的測試.

下面看示例程式碼

我們首先 在頁面中新增如下程式碼

<select name="China" id="zhengzhouDistrict">
    <option value="">--請選擇區域--</option>
    <option value="pdditrict">中原區</option>
    <option value="hpditrict">二七區</option>
    <option value="xhditrict">管城區</option>
    <option value="cnditrict">高新區</option>
    <option value="sjditrict">開發區</option>
</select>

測試程式碼如下:

       [Fact]
        public void DropDownListTest()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);
            driver.Url = "http://localhost:28614/HelloWorld/FormTest";
            driver.Navigate();
            var element = driver.FindElement(By.Id("zhengzhouDistrict"));
            SelectElement dropdownList = new SelectElement(element);
            dropdownList.SelectByIndex(3);
            var select = dropdownList.SelectedOption.Text;
            Assert.Equal("管城區", select);
        }

以上程式碼中我們先是通過普通方法獲取到了這個下拉列表,然後把它封裝成一個SelectElement物件,然後呼叫它的SelectByIndex設定選中的項,這樣選中的項就是不預設值了,而是我們想要選擇的值.

select還有按索引,鍵,值等設定選擇項的方法,並且可以取消選擇,大家自己嘗試一下,這裡不再介紹.

然而以上方法並沒有什麼太大作用,由於瀏覽器自帶的select介面往往都不太美觀,並且動態互動性不是非常好,實際專案中我們很少使用原生的select,而是使用第三方ui框架帶的select,而第三方框架往往都是把select隱藏起來,然後把它的值賦值給一個input元素,它設定和獲取值都是通過第三方框架提供的api而非原生select自帶的方法.如果這時候使用以上方法獲取select元素就會導致失敗,selenium會提交元素被隱藏無法互動.針對這個問題筆者採用了一種比較笨的方法那就是模擬按鍵,當然這裡模擬按鍵並不引入第三方按鍵類框架,而是使用selenium本身的功能.

下面仍然以layui為例說明如何設定下拉列表值.

頁面程式碼如下


<html>
<head>
    <meta name="viewport" content="width=device-width" />

    <link href="~/lib/layui/css/layui.css" rel="stylesheet" />
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/layui/layui.all.js"></script>
    <title>FormTest</title>
</head>
<body>
<form class="layui-form" action="">
    <div class="layui-form-item">
        <div class="layui-input-inline">
            <select name="China" id="zhengzhouDistrict">
                <option value="">--請選擇區域--</option>
                <option value="pdditrict">中原區</option>
                <option value="hpditrict">二七區</option>
                <option value="xhditrict">管城區</option>
                <option value="cnditrict">高新區</option>
                <option value="sjditrict">開發區</option>
            </select>
        </div>
    </div>
</form>
        <script>
            var layer = layui.layer;
            var form = layui.form;
            form.render();
        </script>
</body>
</html>

以上程式碼和上面的類似,只是這裡把它封裝成layui的select,我們的思路是先獲取到layui的顯示select的元素,也就是最終渲染的input元素,經過觀察發現這個元素有一個這樣的樣式layui-input,我們可以通過這個關鍵資訊找到它,然後點選一下,這時候下拉列表就出來了,此時再點擊向下按鈕,在想要的位置處click一下就可以得到想要的結果了.

測試程式碼如下:

       [Fact]
        public void DropDownListTest()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);
            driver.Url = "http://localhost:28614/HelloWorld/FormTest";
            driver.Navigate();
            var input = driver.FindElement(By.ClassName("layui-input"));
            input.Click();
            Actions action = new Actions(driver);
            action.SendKeys(Keys.ArrowDown+Keys.ArrowDown+Keys.ArrowDown).Click().Build().Perform();
        }

以上主要是使用的Actions連續點選兩次向下,就可以選擇到指定的元素了.

日期框處理

這裡結合layui來講解如何處理日期框的問題

首先我們來觀察一下layui日期輸入框的特點,它其實是一個input,並且是可以接受使用者輸入的,這就跟我們模擬手動輸入帶來了方便,但是事情並沒有這麼簡單,我們可以看到手輸內容之後還要點選那個彈出層的確定按鈕來確認輸入,一旦點選了確定則會把彈出層預設選中的日期輸入到input框中,覆蓋了剛才的選擇.然而它卻有以下一個特點:如果我們輸入以後不點選確認,而是把游標移到空白色點選或者游標焦點移到其它可輸入元素內,則也可以確認輸入.這樣我們就可以在日期輸入框輸入內容以後再把焦點移到其它輸入框就能夠確認輸入了.

頁面程式碼如下:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <link href="~/lib/layui/css/layui.css" rel="stylesheet" />
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/layui/layui.all.js"></script>
    <title>FormTest</title>
</head>
<body>
<div class="layui-inline">
    <input type="text" class="layui-input" id="test1">
    <input type="text" id="input1"/>
</div>
<script>
    var laydate = layui.laydate;
    laydate.render({
        elem: '#test1'
    });
</script>
</body>
</html>

以上有兩個input框,一個是普通input,一個是日期框,我們模擬在日期輸入框輸入內容後把焦點移動它右邊空白處點選,然後看看上面日期輸入框裡的值是不是我們賦予的.

測試程式碼如下:

        [Fact]
        public void DropDownListTest()
        {
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory);
            driver.Url = "http://localhost:28614/HelloWorld/FormTest";
            driver.Navigate();
            var input = driver.FindElement(By.Id("test1"));
            input.SendKeys("2008-5-3");
            var position = input.Location;
            var clickposition = position.X + 200;
            Actions actions = new Actions(driver);
            actions.MoveByOffset(clickposition, 0).Click().Build().Perform();
            var txt = input.GetAttribute("value");
            Assert.Equal("2008-05-03", txt);
        }

以上程式碼我們首先獲取到這個日期選擇框,然後給它輸入值.下面我們獲取它的位置主要是為了讓它關閉(如果點選了空白處或者其它可點選控制元件,則日期選擇框就會消失,這裡只所以要關閉它是因為它當前處於啟用狀態,如果不關閉則會影響其它操作).我們獲取到它的位置後向右移動滑鼠到空白處,然後點選空白處日期選擇框就消失了.我們輸入的是'2008-5-3'而斷言它是'2008-05-03'是因為layui有格式糾正功能,自動把一位的資料前面補零.

這裡獲取input的值是通過GetAttribute獲取的,而不是通過Text,text是獲取元素內部的文字(也就是文字包含在標籤裡),而input的值是它的value屬性的一個值,因此使用Text獲取不到.
一定要注意點選位置,如果點選位置位於連結或者提交按鈕上則可能觸發不可預期的效果.

前面我們介紹瞭如何通過普通的方法給元素設定值以及模擬特定的行為,本篇主要介紹如何獲取頁面cookie,如何模擬手機測試.

獲取頁面cookie

有些比較複雜的測試可能會用到cookie,在Selenium裡通過driver.Manage().Cookies就可以獲取到頁面所有的cookie物件了.

模擬手機瀏覽器

由於目前沒有手機專案,這裡並不詳細介紹,只是作為一個知識點簡單介紹一下.

看以下測試程式碼

        [Fact]
        public void DropDownListTest()
        {
            ChromeOptions opts = new ChromeOptions();
            opts.EnableMobileEmulation("iPhone X");
            IWebDriver driver =
                new ChromeDriver(Environment.CurrentDirectory,opts);
            driver.Url = "http://www.baidu.com";
            driver.Navigate();

        }

這裡主要是增加一個谷歌瀏覽器啟用模擬手機瀏覽器選項,並指定一個模擬器的名字(這些名字可以通過谷歌瀏覽器的手機模式檢視).然後再啟動頁面就會在指定的手機模擬器運行了.

以上執行結果截圖如下:

相關推薦

.netcore持續整合測試web專案驗收測試

系列目錄 通過前面的單元測試,我們能夠保證專案的基本模組功能邏輯是正常的,通過整合測試能夠保證介面的請求是正常的.然而最終專案交付我們還需要對專案進行頁面的行為進行測試,比如頁面佈局是否正常,按鈕是否能點選,點選後執行的動作是否正確,連結是否正常等功能進行測試,表單提交是否返回正確結果等.這些都是一些墨盒

.netcore持續整合測試Xunit資料驅動測試

>[系列目錄](https://www.cnblogs.com/tylerzhou/p/11204826.html) Nunit裡提供了豐富的資料測試功能,雖然Xunit裡提供的比較少,但是也能滿足很多場景下使用了,如果資料場景非常複雜,Nunit和Xunit都是無法勝任的,有不少測試者選擇自己編寫一個

.netcore持續整合測試MVC層單元測試

前面我們講的很多單元測試的的方法和技巧不論是在.net core和.net framework裡面都是通用的,但是mvc專案裡有一種比較特殊的類是Controller,首先Controller類的返回結果跟普通的類並不一樣,普通的類返回的都是確定的型別,而mvc專案的返回的ActionResult或者core

.net持續整合sonarqube專案管理與使用者管理

系列目錄 刪除專案 在學習階段,我們可能需要經常刪除已構建的專案,在sonarqube中想要刪除一個專案有兩個入口,都在Administration導航欄內. 在專案內部的管理介面刪除 如果專案處於開啟狀態,如下圖示 點選Administration會出現一個下拉選單,其中最後一項為Deletion,

.net持續整合sonarqube sonarqube整合單元測試

系列目錄 通過前面章節我們可以看到,不論怎麼構建,單元測試覆蓋率一欄總是0% 這是因為單元測試覆蓋率報告需要額外整合.這一節我們就講解如何在sonarqube裡整合單元測試覆蓋率報告. 這裡需要藉助Opencover來生成單元測試覆蓋報告文件,Opencover前面章節我們介紹過,不瞭解的朋友可以檢

.net持續整合測試Nunit引數化測試

系列目錄 在進行單元測試的時候,很多時候,很多時候我們都是在單元測試方法內部提供特定的值,但是這樣測試往往造成樣本數不足從而導致覆蓋的結果不夠全面,很多時候我們更想提供來自外部的,滿足條件的一組值來進行測試.其實Nunit框架本身提供了為測試用例提供值的能力.我們可以對它進行擴充套件來實現匯入外部的值來填

.net持續整合cakecake介紹及簡單示例

cake介紹 Cake 是.net平臺下的一款自動化構建工具,可以完成對.net專案的編譯,打包,執行單元測試,整合測試甚至釋出專案等等.如果有些特徵Cake沒有實現,我們還可以很容易地通過擴充套件Cake來實現我們想要的功能. Cake有以下特點 1) 使用c#語言編寫,可以在Cake腳本里使用C#語言來實

.net持續整合cakecake任務依賴、自定義配置薦及環境變數讀取

系列目錄 新建一個構建任務及任務依賴關係設定 上節我們通過新建一個HelloWorld示例講解了如何編寫build.cake以及如何下載build.ps1啟動檔案以及如何執行.實際專案中,我們使用最多的是對專案進行編譯.本節我們講解如何建立一個編譯任務. 新增一個編譯任務 我們仍然使用上節使用的build

.net持續整合sonarqubesonarqube安裝與基本配置

系列目錄 Sonarqube下載與安裝 Sonarqube下載地址是:https://www.sonarqube.org/downloads/下載版本有兩個,一個是長期支援版,另一個是最新版,此處安裝的是最新版,目前版本是7.3,下載的時候點選醒目的藍色按鈕即可(此時下載的是社群版),下面有三個無底色按鈕

.net持續整合sonarqubesonarqube基本操作(一)

系列目錄 Sonarqube Web管理介面雖然設計的簡潔大方,也非常直觀,但是由於功能繁多,這對快速入手以及快速定位到想要的功能都是一個挑戰,在以後的幾個小節裡我們簡要介紹. OwerView(概覽) 概覽介面主要展示了專案lint的統計資訊 可以看到這些欄目欄目大都是統計數字,並且帶有連結,點選連

.net持續整合sonarqubesonarqube基本操作(二)

系列目錄 Activity介面操作 Activity介面主要是對多次構建管理介面,主要是幫助管理員快速瞭解專案每次構建與以往構建相比問題是增加了還是減少了等指標.由於目前我們僅進行了一次構建,因此沒有對比資料,我們再對測試專案進行一次構建. 構建程式碼如下 SonarScanner.MSBuild.exe

.net持續整合sonarqube sonarqube與jenkins整合(命令模式)

系列目錄 Sonarqube結合Jenkins與常見問題 我們引入sonarqube元件的最終目的是要為整個Ci環境服務的,如果不能集成於當前的Jenkins CI,那麼我們做的很多關於sonarqube的工作都將是徒勞的.然而這一點幾乎不用擔心,因為我們從前面的講解可以看到我們的構建操作都是通過命令列來

.net持續整合sonarqube sonarqube與jenkins整合(外掛模式)

系列目錄 Jenkins通過外掛整合Sonarqube 通過上一節我們瞭解瞭如何配置以使jenkins ci環境中可以執行sonarqube構建,其實Sonarqube官方也提供了jenkins外掛以便更方便的管理.使用外掛來執行sonarqube專案有以下優點 1.可以很清楚的看到專案是Sonarqub

持續整合高階Jekins指令碼引數化構建

系列目錄 本系列已經很久沒有更新了,接前面基礎篇,本系統主要介紹jenkins構建裡的一些高階特性.包括指令碼引數化,Jenkins Pipeline與及在PipeLine模式下如何執行常見的傳統構建任務(這裡指jenkins自由風格構建模式),jenkins cli,jenkins ssh,jenki

持續整合高階Jekins引數化構建(二)

系列目錄 上一節我們講解了如何使用bat指令碼或者powershell指令碼自身的機制來達到引數化構建的目的,這在一定程式上增加了靈活性,然而缺點也相當明顯:它只能適應一些相對比較固定的引數傳入(比如像上一節講到的,構建的環境分為(development和production)兩種情況,對於一些相對較複雜

持續整合高階Jekins引數傳入與常見任務

系列目錄 有的童鞋可能已經發現,PipeLine專案與自由式專案相比,可配置的項少了很多,比如說環境變數定義,所有步驟完成後執行動作,拉git程式碼庫等.其實這些功能並沒有缺,而是配置的方式不一樣了,以前是通過圖形化介面配置,雖然直觀簡便,但是功能不能包羅萬像,對於一些複雜的專案顯得捉襟見肘,而Jenki

持續整合高階Jenkins Pipeline git拉取

系列目錄 PipeLine中拉取遠端git倉庫 前面講自由式任務的時候,我們可以看到通過自由式job裡提供的圖形介面配置git拉取非常方便的,實際上使用PipeLine也並不複雜.這一節我們展示一下如何在PipeLine任務中拉取git倉庫程式碼. node{ stage("check

持續整合高階Jenkins cli與Jenkins ssh

系列目錄 Jenkins Cli介紹 Jenkins Cli為Jenkins提供的一個cli工具,此工具功能非常強大,可以完成諸如重啟jenkins,建立/刪除job,檢視job控制檯輸出,新增/刪除節點等功能.但是實際工作中,像建立任務這樣的配置顯然cli非常吃力,不如直接在web管理介面操作,但是對於

持續整合高階基於win32-openssh搭建jenkins混合叢集(一)

系列目錄 前面的demo我們使用的都是隻有一個windows主節點的的jenkins,實際生產環境中,一個節點往往是不能滿足需求的.比如,.net專案要使用windows節點構建,java專案如果部署在linux伺服器上往往也需要目標型別的linux節點做為構建節點,開發中使用的jdk版本不同也可能需要不

持續整合高階Jenkins資源排程

系列目錄 之前的示例我們主要關注點在於功能的實現,都是在一個節點的完成了.有了多個節點後,必須涉及到資源的排程問題.本節我們講解在建立任務時與資源排程的有關選項以及一些平時沒有注意到的但在生產環境需要精細控制的選項. 我們隨便建立一個自由式風格任務,這裡主要講解General裡的一些選項 Restrict