用流程
1. 定義測試用例
2. 驗證測試用例
以示例接口 新聞列表為例,新聞列表返回響應數據如下:
```javascript
{
"code": 10000,
"msg": "success",
"data": {
"cur_page": "1",
"last_page": 2,
"page_size": "20",
"total": 30,
"list": [
{
"id": 3,
"title": "前后僅用了4分鐘,16枚洲際導彈應聲而出,美航母也不敢輕舉妄動",
"author": "烽火雜志",
"url": "https://open.apipost.cn/",
"content": "世界上哪個國家可與美軍抗衡?國際社會上關于這一問題的答案千奇百怪,但有一個國家用行動讓美軍閉嘴,短短4分鐘連續發射16枚洲際導彈,場面十分壯觀,讓西方國家畏懼不已,即便是美航母也不敢輕舉妄動。"
}
]
}
}
```
定義入口在后執行腳本里;
特別注意:==每個測試用例是一行,不能換行。==
通用和常用的測試用例定義如下:
```javascript
apt.assert('response.raw.responseText=="test"');
apt.assert('response.raw.status==200');
apt.assert('response.raw.type=="json"');
apt.assert('response.raw.responseTime>=100');
apt.assert('response.json.errcode==1');
apt.assert('response.json.errcode!=1');
apt.assert('response.json.errcode>=1');
apt.assert('response.json.errcode==null');
apt.assert('response.json.errcode!=null');
apt.assert('response.headers["server"]=="nginx"');
apt.assert('response.headers["content-encoding"]=="gzip"');
apt.globals.set("key", "value");
apt.globals.get("key");
apt.globals.delete("key");
apt.globals.clear();
apt.variables.set("key", "value");
apt.variables.get("key");
apt.variables.delete("key");
apt.variables.clear();
$.ajax({
"url":"https://echo.apipost.cn/token.php",
"method":"POST",
"async":false,
"content-type":"appicateion-json",
"data":JSON.stringify({
"email":"admin@admin.com",
"password":"密碼"
}),
"success":function(response){
response=typeof response=="object" ? response : JSON.parse(response);
console.log(response);
apt.variables.set("token", response.token);
}
});
```
針對新聞列表這個接口測試用例定義如下:
```javascript
apt.assert('response.raw.status==200');
apt.assert('response.raw.type=="json"');
apt.assert('response.raw.responseTime>=100');
apt.assert('response.json.code==10000');
apt.assert('response.json.msg=="success"');
apt.assert('response.raw.responseText.indexOf("data") > -1'); // 檢查響應文本是否含有data字符串
apt.assert('response.json.hasOwnProperty("data")'); // 檢測返回json對象的是否含有data字段
apt.assert('response.json.data.cur_page=="1"');
apt.assert('response.json.data.last_page==2');
apt.assert('response.json.data.page_size=="20"');
apt.assert('response.json.data.total==30');
```
下圖為運行效果圖
綠色表示測試通過,紅色表示測試不通過
再加一個明顯不通過的定義:apt.assert('response.raw.responseText=="test"');
```javascript
apt.assert('response.raw.responseText=="test"');
apt.assert('response.raw.status==200');
apt.assert('response.raw.type=="json"');
apt.assert('response.raw.responseTime>=100');
apt.assert('response.json.code==10000');
apt.assert('response.json.msg=="success"');
apt.assert('response.raw.responseText.indexOf("data") > -1'); // 檢查響應文本是否含有data字符串
apt.assert('response.json.hasOwnProperty("data")'); // 檢測返回json對象的是否含有data字段
apt.assert('response.json.data.cur_page=="1"');
apt.assert('response.json.data.last_page==2');
apt.assert('response.json.data.page_size=="20"');
apt.assert('response.json.data.total==30');
```
結果如圖:
定義如下:
```javascript
//驗證集合list測試用例定義;
// 筆者暫時還沒有找到添加斷言業務描述的參數方法,一般斷言有斷言描述和斷言表達式。但這個語法上好像不支持。
// 后期如果找到一并補充上
if(response.json.hasOwnProperty("data")){
// apt.assert('response.raw.responseText=="test"');
if(response.json.data.hasOwnProperty("list")
&& response.json.data.list.length>0){
// apt.assert('response.raw.responseText=="test"');
for(var i=0;i<response.json.data.list.length;i++){
apt.assert(true,"i="+i);
var item=response.json.data.list[i];
response.json.data.item=item;
apt.assert('response.json.data.item.hasOwnProperty("id")');
apt.assert('response.json.data.item.hasOwnProperty("title")');
apt.assert('response.json.data.item.hasOwnProperty("author")');
apt.assert('response.json.data.item.hasOwnProperty("url")');
apt.assert('response.json.data.item.hasOwnProperty("content")');
}
}
}
```
結果見下圖:
筆者暫時還沒有找到添加斷言業務描述的參數方法,一般斷言有斷言描述和斷言表達式。但這個語法上好像不支持。后期如果找到一并補充上
示例接口由于是動態環境,所以數據值會發生變化,不利于進行原始數據與后期接口獲取的數據進行數據文件上的驗證。
如不理解沒有關系,這個屬于業務數據驅動接口測試的一種測試理念。一般在大型且各種資源比較充沛的團隊才進行這樣的從服務環境、數據庫、業務數據添加,修改,刪除等一系列流程上完全被定義可預測且能驗證的整體可測的測試設計。
不過筆者搞開發十多年也沒有見過這樣的大手筆。可能大廠有吧!一般幾十剛過百人的研發團隊就算了。沒那必要性。
不過如果是支撐大流量且需要在高速奔跑火車上換換輪子的極端情況,搞這么一個十個人左右的小的數據驅動一切可測設計的測試團隊還是有比較可觀的收益的。這樣可評估線上生產環境的風險范圍以及當前研發團隊的研發質量和風險意識。
期待擴展出使用json等格式文件進行數據斷言的版本
搞開發這些年見過很多給開發打績效的方案:
比如:按代碼量的,按工時的,按編碼時長的,按提交數量的等等方式。只能說有比沒有好吧!在表面搞搞人力績效還是很能讓老板滿意的,于是各種加班996,007就出現了。
其實開發質量是可以從API接口測試里體現出來的能兼容的場景參數越多,服務越穩定。技術當然會比較好。當然筆者的觀點估計不好理解和接受。這種用單元測試來衡量開發質量的還得是開發自己人來搞。不過接口工具的出現到提供了非開發人員來量化開發人員質量,也許是不錯的方式。
言
處理網頁數據時,我們經常需要從HTML中提取日期信息。日期格式多樣,從HTML文檔中準確地提取并驗證這些信息是一項挑戰。本文將詳細介紹如何使用正則表達式從HTML中提取日期,并用Python代碼進行有效性驗證。
一、正則表達式基礎
概念:
正則表達式是用于文本搜索和替換的強大工具,它能夠描述復雜的模式。
基本語法元素:
字符集:[0-9]匹配任意數字,[a-zA-Z]匹配任意字母。
量詞:*(零次或多次)、+(一次或多次)等。
特殊字符:.匹配任意單個字符,\d匹配任意數字。
分組:(19|20)\d\d匹配以19或20開頭的年份。
二、從HTML中提取日期
HTML結構分析:
檢查網頁源代碼,找到包含日期的標簽或屬性。
日期可能以不同格式存在,比如文本形式或屬性值。
構建正則表達式:
針對YYYY-MM-DD、DD-MM-YYYY、MM/DD/YYYY等格式編寫正則表達式。
考慮HTML文檔結構的差異,調整正則表達式以提高匹配的準確性。
三、驗證日期的有效性
日期格式驗證:
確保提取的字符串符合日期格式,但還需要進一步驗證日期的實際有效性。
正則表達式初步驗證:
使用正則表達式確保日期組件在合理范圍內,如月份應在01至12之間。
編程驗證日期有效性:
使用Python的datetime模塊進行進一步驗證。
考慮特殊情況,如閏年和每月的實際天數。
四、實際案例分析
案例演示:
選取具有代表性的網頁HTML樣本,標識其中的日期信息。
編寫適用的正則表達式來匹配這些日期。
代碼實現:
使用Python演示如何應用正則表達式提取日期。
展示如何使用datetime模塊驗證日期有效性。
五、總結與展望
總結:
正則表達式是提取HTML中日期信息的有效工具,但還需通過編程驗證其有效性。
未來應用:
探討正則表達式在數據分析、日志處理等領域的應用。
小結
本文提供了一個全面的指南,說明了如何使用正則表達式從HTML文檔中提取日期,并通過Python代碼進行驗證。這些技能對于數據抓取和文本處理領域非常重要。
Python 代碼示例
1. 正則表達式提取日期
python
import re
from datetime import datetime
# 示例HTML內容
html_content="""
<p>發表日期:2020-12-15</p>
<p>更新日期:2021/01/20</p>
<p>活動日期:31-01-2022</p>
"""
# 正則表達式匹配不同的日期格式
date_patterns=[
r'\d{4}-\d{2}-\d{2}', # YYYY-MM-DD
r'\d{2}/\d{2}/\d{4}', # DD/MM/YYYY
r'\d{2}-\d{2}-\d{4}' # DD-MM-YYYY
]
# 提取日期
extracted_dates=[]
for pattern in date_patterns:
matches=re.findall(pattern, html_content)
extracted_dates.extend(matches)
print("Extracted Dates:", extracted_dates)
2. 驗證日期有效性
python
# 驗證日期有效性
def validate_date(date_str):
for fmt in ("%Y-%m-%d", "%d/%m/%Y", "%d-%m-%Y"):
try:
datetime.strptime(date_str, fmt)
return True
except ValueError:
continue
return False
# 驗證提取的日期
valid_dates=[date for date in extracted_dates if validate_date(date)]
print("Valid Dates:", valid_dates)
在這個例子中,我們首先使用正則表達式從HTML內容中提取日期,然后使用Python的datetime模塊驗證這些日期的有效性。這種方法適用于不同格式的日期,并能有效地識別和排除無效日期。
validator.js是一個Github上專門針對字符串校驗所建立的一個工具庫,validator.js包含了大量實用的字符串校驗和清洗方法,并且支持在Node環境和瀏覽器環境使用,非常實用。
https://github.com/validatorjs/validator.js
包管理方式安裝
npm install validator
//或者
yarn add validator
可以在各種開發場景下使用
var validator=require('validator');
validator.isEmail('foo@bar.com'); //=> true
可以一次性全部導入
import validator from 'validator';
也可以針對不同方法單獨引入,比如我們只需要導入驗證郵箱的方法
import isEmail from 'validator/lib/isEmail';
或者Tree-shakeable ES imports導入
import isEmail from 'validator/es/lib/isEmail';
<script type="text/javascript" src="validator.min.js"></script>
<script type="text/javascript">
validator.isEmail('foo@bar.com'); //=> true
</script>
方法非常豐富,可以根據需要進行使用,建議先看一下Github上中每個方法的含義和使用方式。
import toDate from './lib/toDate';
import toFloat from './lib/toFloat';
import toInt from './lib/toInt';
import toBoolean from './lib/toBoolean';
import equals from './lib/equals';
import contains from './lib/contains';
import matches from './lib/matches';
import isEmail from './lib/isEmail';
import isURL from './lib/isURL';
import isMACAddress from './lib/isMACAddress';
import isIP from './lib/isIP';
import isIPRange from './lib/isIPRange';
import isFQDN from './lib/isFQDN';
import isDate from './lib/isDate';
import isBoolean from './lib/isBoolean';
import isLocale from './lib/isLocale';
import isAlpha, { locales as isAlphaLocales } from './lib/isAlpha';
import isAlphanumeric, { locales as isAlphanumericLocales } from './lib/isAlphanumeric';
import isNumeric from './lib/isNumeric';
import isPassportNumber from './lib/isPassportNumber';
import isPort from './lib/isPort';
import isLowercase from './lib/isLowercase';
import isUppercase from './lib/isUppercase';
import isIMEI from './lib/isIMEI';
import isAscii from './lib/isAscii';
import isFullWidth from './lib/isFullWidth';
import isHalfWidth from './lib/isHalfWidth';
import isVariableWidth from './lib/isVariableWidth';
import isMultibyte from './lib/isMultibyte';
import isSemVer from './lib/isSemVer';
import isSurrogatePair from './lib/isSurrogatePair';
import isInt from './lib/isInt';
import isFloat, { locales as isFloatLocales } from './lib/isFloat';
import isDecimal from './lib/isDecimal';
import isHexadecimal from './lib/isHexadecimal';
import isOctal from './lib/isOctal';
import isDivisibleBy from './lib/isDivisibleBy';
import isHexColor from './lib/isHexColor';
import isRgbColor from './lib/isRgbColor';
import isHSL from './lib/isHSL';
import isISRC from './lib/isISRC';
import isIBAN, { locales as ibanLocales } from './lib/isIBAN';
import isBIC from './lib/isBIC';
import isMD5 from './lib/isMD5';
import isHash from './lib/isHash';
import isJWT from './lib/isJWT';
import isJSON from './lib/isJSON';
import isEmpty from './lib/isEmpty';
import isLength from './lib/isLength';
import isByteLength from './lib/isByteLength';
import isUUID from './lib/isUUID';
import isMongoId from './lib/isMongoId';
import isAfter from './lib/isAfter';
import isBefore from './lib/isBefore';
import isIn from './lib/isIn';
import isCreditCard from './lib/isCreditCard';
import isIdentityCard from './lib/isIdentityCard';
import isEAN from './lib/isEAN';
import isISIN from './lib/isISIN';
import isISBN from './lib/isISBN';
import isISSN from './lib/isISSN';
import isTaxID from './lib/isTaxID';
import isMobilePhone, { locales as isMobilePhoneLocales } from './lib/isMobilePhone';
import isEthereumAddress from './lib/isEthereumAddress';
import isCurrency from './lib/isCurrency';
import isBtcAddress from './lib/isBtcAddress';
import isISO8601 from './lib/isISO8601';
import isRFC3339 from './lib/isRFC3339';
import isISO31661Alpha2 from './lib/isISO31661Alpha2';
import isISO31661Alpha3 from './lib/isISO31661Alpha3';
import isISO4217 from './lib/isISO4217';
import isBase32 from './lib/isBase32';
import isBase58 from './lib/isBase58';
import isBase64 from './lib/isBase64';
import isDataURI from './lib/isDataURI';
import isMagnetURI from './lib/isMagnetURI';
import isMimeType from './lib/isMimeType';
import isLatLong from './lib/isLatLong';
import isPostalCode, { locales as isPostalCodeLocales } from './lib/isPostalCode';
import ltrim from './lib/ltrim';
import rtrim from './lib/rtrim';
import trim from './lib/trim';
import escape from './lib/escape';
import unescape from './lib/unescape';
import stripLow from './lib/stripLow';
import whitelist from './lib/whitelist';
import blacklist from './lib/blacklist';
import isWhitelisted from './lib/isWhitelisted';
import normalizeEmail from './lib/normalizeEmail';
import isSlug from './lib/isSlug';
import isLicensePlate from './lib/isLicensePlate';
import isStrongPassword from './lib/isStrongPassword';
import isVAT from './lib/isVAT';
validator.js是一個非常值得學習的工具庫,不僅是使用它,也可以用它來學習一些JavaScript的基礎知識,學習其中各類方法的寫法,也可以鞏固JavaScript的基礎知識!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。