1. 程式人生 > >TestNG入門教程 斷言之HardAssert和SoftAssert

TestNG入門教程 斷言之HardAssert和SoftAssert

       本篇來介紹TestNG中的Assertion,也是斷言。前面介紹了@Test註釋下大部分的屬性的功能和基本使用。這篇介紹,寫測試用例中的斷言部分。我們知道,一個測試用例的水平高低,主要是看斷言的水平。斷言能體現出測試的思維和測試角度,所以斷言是測試中最難寫的部分,自動化測試用例最難的也是在斷言。

舉例一個介面測試的常見流程

1)  傳送介面請求

2)  斷言介面響應狀態是不是200 OK

3)  斷言介面的響應時間低於某一個值(看情況,不是必選)

4)  斷言響應資料是否正確,一般的做法是判斷某一個值是否相等或者包含關係

       基本上就是這麼一個測試流程,其中4)部分的斷言最難寫。因為介面請求回來,會得到很多引數返回,一般是json資料,有些公司只能夠對其中幾個json字串進行斷言比較,有些能夠通過兩個json檔案對比,一個是直接從資料庫請求的json資料檔案,一個是介面請求得到的json檔案。下面,我們來看看TestNG給我們提供了哪些斷言操作。TestNG中最常用的一個斷言類是Assert.java,裡面有多個靜態方法,這個類我們習慣叫硬斷言。對應的還有一個軟斷言的類,叫SoftAssert.java,這個類是需要建立例項物件,才能呼叫相關例項方法進行軟斷言。

1. Assert類(硬斷言)

1)  Assert.assertEquals(actual, expected)


TestNG中提供了多個33個assertEquals()方法,主要是匹配不同的資料型別和集合類操作。我們最常用的就是assertEquals(actual, expected)或者assertEquals(actual,expected,“message1”)

舉例:


  
  1. package testng;
  2. import org.testng.Assert;
  3. import org.testng.annotations.Test;
  4. public class AssertionTest {
  5. @Test
  6. public void AssertTest(){
  7. Assert.assertEquals( 12, 12);
  8. Assert.assertEquals( "ABc", "ABC", "not equals");
  9. }
  10. }

       上面可以看出assertEquals(actual,expected,“message1”)中,如果現實結果和期待結果不相等,丟擲斷言異常並顯示message1的內容,上面紅圈就是我們填寫的message1的內容。自動化測試一般喜歡帶上這個message1,這樣丟擲錯誤,更能快速讀懂錯誤的原因和錯誤的具體業務邏輯。

2)  assertEqualsNoOrder(actual, expect

判斷兩個物件是否相同,忽略排序位置。例如下面的兩個字串陣列比較。

舉例


  
  1. package testng;
  2. import org.testng.Assert;
  3. import org.testng.annotations.Test;
  4. public class AssertionTest {
  5. @Test
  6. public void AssertTest(){
  7. String[] st1 = { "Anthony", "Tom", "Jhon"};
  8. String[] st2 = { "Jhon", "Anthony", "Tom"};
  9. Assert.assertEqualsNoOrder(st1, st2, "兩個字串陣列不相同");
  10. }
  11. }

3)  assertFalse(布林條件,“message1”)

這裡來一個斷言為假的方法,斷言一個條件,如果返回是假,則測試通過,如果返回是真,丟擲斷言異常,列印message1的內容。

舉例:


  
  1. package testng;
  2. import org.testng.Assert;
  3. import org.testng.annotations.Test;
  4. public class AssertionTest {
  5. @Test
  6. public void AssertTest(){
  7. String[] st1 = { "Anthony", "Tom", "Jhon"};
  8. String[] st2 = { "Jhon", "Anthony", "Tom"};
  9. Assert.assertFalse(st1==st2, "兩個相等");
  10. }
  11. }

上面兩個字串陣列,如果考慮排序位置,肯定兩者不相等。

4)  assertNotEquals(actual, expect, “message1”)

提供“不相等”斷言方法,也是有6個針對不同資料型別的不相等的斷言方法。這裡我們介紹兩個物件的不相等舉例,如果相等,輸出message1的內容。

舉例:


  
  1. package testng;
  2. import org.testng.Assert;
  3. import org.testng.annotations.Test;
  4. public class AssertionTest {
  5. @Test
  6. public void AssertTest(){
  7. String[] st1 = { "Anthony", "Tom", "Jhon"};
  8. String[] st2 = { "Jhon", "Anthony", "Tom"};
  9. Assert.assertNotEquals(st1, st2, "兩者相等");
  10. }
  11. }

5)  assertNotNull(object, “message1”)

物件非空判斷,斷言物件不為空,否則,丟擲異常,列印message1的內容。

舉例:


 

  
  1. package testng;
  2. import org.testng.Assert;
  3. import org.testng.annotations.Test;
  4. public class AssertionTest {
  5. @Test
  6. public void AssertTest(){
  7. String[] st1 = { "Anthony", "Tom", "Jhon"};
  8. String[] st2 = { "Jhon", "Anthony", "Tom"};
  9. String[] st3 = null;
  10. Assert.assertNotNull(st1, "該物件為空");
  11. Assert.assertNotNull(st3, "該物件為空");
  12. }
  13. }

上面執行後,st3會報斷言異常。

6)  assertSame(actual, expect, “message”)

斷言兩個物件相同,這裡相同和上面的Equals不同,Equals是值比較,而Same是記憶體地址比較。直接來看下面例子。


  
  1. package testng;
  2. import org.testng.Assert;
  3. import org.testng.annotations.Test;
  4. public class AssertionTest {
  5. @Test
  6. public void AssertTest(){
  7. String[] st1 = { "Anthony", "Tom", "Jhon"};
  8. String[] st2 = { "Jhon", "Anthony", "Tom"};
  9. String[] st3 = st1;
  10. Assert.assertSame(st1, st3, "not same");
  11. Assert.assertSame(st1, st2, "not same");
  12. }
  13. }

7)  assertNotSame(actual, expect, “message”)

同樣的,也有斷言兩個物件記憶體地址不相同的斷言方法。

舉例:


  
  1. package testng;
  2. import org.testng.Assert;
  3. import org.testng.annotations.Test;
  4. public class AssertionTest {
  5. @Test
  6. public void AssertTest(){
  7. String[] st1 = { "Anthony", "Tom", "Jhon"};
  8. String[] st2 = { "Jhon", "Anthony", "Tom"};
  9. String[] st3 = st1;
  10. Assert.assertNotSame(st1, st2, "same");
  11. }
  12. }

       上面st1和st2肯定記憶體地址不相同,所以assertNotSame是執行通過,如果把st2改成st3,這個就會丟擲異常並列印same這個字元訊息,因為st1和st3指向同一個記憶體位置。

8)  assertTrue(條件表示式, “message1”)

       提供了斷言一個條件為真的方法,如果條件表示式為真,該斷言執行通過,如果表示式為假,丟擲異常,列印message1的訊息。

舉例:


  
  1. package testng;
  2. import org.testng.Assert;
  3. import org.testng.annotations.Test;
  4. public class AssertionTest {
  5. @Test
  6. public void AssertTest(){
  7. String[] st1 = { "Anthony", "Tom", "Jhon"};
  8. String[] st2 = { "Jhon", "Anthony", "Tom"};
  9. String[] st3 = st1;
  10. Assert.assertTrue(st1==st3, "兩者不相同");
  11. }
  12. }

2.  SoftAssert(軟斷言)

       在Assert.java這個類中,上面我們已經介紹了大部分的斷言方法。這些斷言方法都是叫硬斷言。硬斷言就是,如果執行到折行斷言失敗,即使該用例,後面還有其他程式碼行,也不會繼續執行下去。有時候我們不希望這種情況出現,SoftAssert就很好地幫我們解決了這個問題。

SoftAssert的特點

1)  如果一個斷言失敗,會繼續執行這個斷言下的其他語句或者斷言。

2)  也就是一個用例有多個斷言,失敗了其中一個,不影響其他斷言的執行

3)  不要忘記呼叫assertAll()在該用例的最後一個斷言後面。

舉例:


  
  1. package testng;
  2. import org.testng.annotations.Test;
  3. import org.testng.asserts.SoftAssert;
  4. public class AssertTestDemo {
  5. @Test
  6. public void testSoftAssert(){
  7. System.out.println( "Test start");
  8. SoftAssert assertion = new SoftAssert();
  9. assertion.assertEquals( 12, 13, "兩者不相等");
  10. System.out.println( "Test complete");
  11. System.out.println( 3+ 8);
  12. assertion.assertAll();
  13. }
  14. }

執行結果:

       通過執行結果截圖,我們可以看到在斷言12和13相等的這行程式碼後面還有其他的語句,如果這裡採用的是Hard Assert,那麼Test complete 和 11是不會輸出,也就是程式碼沒有被執行。這個就是SoftAssert的優點,再強調一次,最後一定要呼叫assertAll()方法。





				<script>
					(function(){
						function setArticleH(btnReadmore,posi){
							var winH = $(window).height();
							var articleBox = $("div.article_content");
							var artH = articleBox.height();
							if(artH > winH*posi){
								articleBox.css({
									'height':winH*posi+'px',
									'overflow':'hidden'
								})
								btnReadmore.click(function(){
									articleBox.removeAttr("style");
									$(this).parent().remove();
								})
							}else{
								btnReadmore.parent().remove();
							}
						}
						var btnReadmore = $("#btn-readmore");
						if(btnReadmore.length>0){
							if(currentUserName){
								setArticleH(btnReadmore,3);
							}else{
								setArticleH(btnReadmore,1.2);
							}
						}
					})()
				</script>
				</article>