Сегодня всё больше веб-приложений переходит на архитектуру RESTful, предоставляя пользователям набор REST API. Это позволяет пользователям вызывать различные API и создавать свои приложения. Из этого следует, что затраты на разработку веб-приложений будут снижаться, поскольку нет необходимости поддерживать отдельные информационные "острова", а вместо этого используются REST API для взаимодействия.
Как обеспечить стабильность и корректность REST API? Полная и всесторонняя проверка обязательна. Java-разработчики часто используют JUnit для тестирования своих REST API, но это скорее "белое" тестирование, когда разработчик знает, какой класс или метод он проверяет, а не тестирование с точки зрения пользователя.
Реализовано вторичное упаковывание часто используемых методов запросов API на основе Rest Assured, HttpClient и других, включая (sendPost, sendGet, getJsonResult) и др., что делает использование более удобным.2. Реализованы SQL операции с использованием баз данных Oracle, MySQL и других, включающие (INSERT INTO, DELETE, UPDATE, QUERY) и выполнение "хранящих процедур".
Реализованы возможности получения данных из баз данных Oracle, MySQL и других, включая получение значений полей таблиц, запись этих значений в параметрах документов Excel и последующее использование этих параметров при вызовах API.
Реализованы возможности чтения и записи данных в документах Excel, включая (SheetName, ReadData, WriteData) и другие, основной контент которых соответствует шагам написания тестовых случаев, что делает создание тестовых сценариев проще.
Реализованы возможности ассертов данных в документах Excel, включая сравнение ожидаемых и фактических результатов, автоматическое занесение результатов при провале проверочных точек, возможность просмотра результатов в отчетах тестирования, где провал одной проверочной точки не влияет на выполнение последующих тестовых случаев.
Реализованы возможности вторичной обработки отчетов тестирования, создаваемых на основе ExtentReports и TestNG, что делает интерфейсы более эстетически приятными и содержание более понятным.
package com.jmoney.luckeylink.handler;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.testng.Assert;
import org.testng.Reporter;
import com.jmoney.luckeylink.controller.Login_Controller;
import com.jmoney.luckeylink.util.ExcelUtil;
import com.jmoney.luckeylink.util.MobileApiToolsUtil;
import com.jmoney.luckeylink.util.StringUtil;
import com.jmoney.luckeylink.util.DecodeUnicodeUtil;
public class Login_Handler {
private static Logger logger = Logger.getLogger(Login_Handler.class);
static int TITLE_LINE_INDEX = 5; // Индекс строки с заголовком тест-кейса
static int ARG_NAME_NUMBER = 2; // Количество необходимых аргументов в интерфейсе
static int ACT_NUMBER = 8; // Количество аргументов для проверки в интерфейсе
static String PARAM = null; // Аргументы интерфейса
static String MSG_ACT = null;
/**
* Получение данных из Excel
* @author Liu Zhi King
* @date 2018-04-20 18:01:04
*/
public static void GetExcelInstance() {
logger.info(Login_Handler.class);
System.out.println(Login_Handler.class);
ExcelUtil.getInstance().setFilePath("src/test/java/TestCasexls/JMoney.Luckeylink.Api.xlsm");
ExcelUtil.getInstance().setSheetName("Login");
}
}
``` /**
* <br>Инициализация данных из Excel</br>
* @author Liu Zhi King
* @date 2018-04-20 18:01:04
*/
public static void InitializeExcelData() {
GetExcelInstance();
int color = 4;
try {
logger.info("Инициализация: " + ExcelUtil.getInstance().getFilePath() + ", " + ExcelUtil.getInstance().getSheetName());
System.out.println("Начало инициализации: " + ExcelUtil.getInstance().getFilePath() + ", " + ExcelUtil.getInstance().getSheetName());
MobileApiToolsUtil.initializeData(TITLE_LINE_INDEX, "" + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3) + "", "", color);
System.out.println("Процесс инициализации: " + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3) + " столбец");
if (ACT_NUMBER < 1) {
for (int i = 1; i < ACT_NUMBER + 6; i++) {
MobileApiToolsUtil.initializeData(TITLE_LINE_INDEX, "" + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ARG_NAME_NUMBER + ACT_NUMBER + i) + "", "", color);
System.out.println("Процесс инициализации: " + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ARG_NAME_NUMBER + ACT_NUMBER + i) + " столбец");
}
} else if (ACT_NUMBER == 1) {
for (int i = 1; i < ACT_NUMBER + 6; i++) {
MobileApiToolsUtil.initializeData(TITLE_LINE_INDEX, "" + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ARG_NAME_NUMBER + ACT_NUMBER + i) + "", "", color);
System.out.println("Процесс инициализации: " + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ARG_NAME_NUMBER + ACT_NUMBER + i) + " столбец");
}
} else if (ACT_NUMBER > 1) {
for (int i = 1; i < ACT_NUMBER + 1; i++) {
if (StringUtil.isEqual(ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ARG_NAME_NUMBER + 2 * i),
ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ARG_NAME_NUMBER + 2 * i + 2))) {
System.out.println("Проверка значения: " + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ARG_NAME_NUMBER + 2 * i));
}
}
}
}
}```markdown
readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + 2 * i) + " повторяется, проверьте данные и попробуйте снова! ";
System.exit(0);
} else {
MobileApiToolsUtil.initializeData(TITLE_LINE_INDEX,
"" + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + 2 * i) + "",
"", color);
System.out.println("Инициализация началась: " + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + 2 * i) + " столбец");
}
}
MobileApiToolsUtil.initializeData(TITLE_LINE_INDEX,
"" + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 1) + "",
"", color);
System.out.println("Инициализация началась: " + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 1) + " столбец");
MobileApiToolsUtil.initializeData(TITLE_LINE_INDEX,
"" + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 2) + "",
"", color);
System.out.println("Инициализация началась: " + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 2) + " столбец");
MobileApiToolsUtil.initializeData(TITLE_LINE_INDEX,
"" + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 3) + "",
"", color);
System.out.println("Инициализация началась: " + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 3) + " столбец");
MobileApiToolsUtil.initializeData(TITLE_LINE_INDEX,
"" + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 4) + "",
"", color);
System.out.println("Инициализация началась: " + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 4) + " столбец");
println("Инициализация началась: " + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 4) + " столбец");
readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 4) + " 列";
MobileApiToolsUtil.initializeData(TITLE_LINE_INDEX, "" + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 5) + "", "", цвет);
System.out.println("正在初始化:" + ExcelUtil.getInstance().readExcelCell(TITLE_LINE_INDEX, 3 + ArgName_Number + Act_Number * 2 + 5) + " 列");
}
logger.info(ExcelUtil.getInstance().getFilePath() + ", " + ExcelUtil.getInstance().getSheetName() + " 初始化完成");
System.out.println(ExcelUtil.getInstance().getFilePath() + ", " + ExcelUtil.getInstance().getSheetName() + " 初始化完成");
System.out.println("===================================================================");
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Инициализация завершена: " + ExcelUtil.getInstance().getFilePath() + ", " + ExcelUtil.getInstance().getSheetName());
System.out.println("===================================================================");
} catch (IOException e) {
e.printStackTrace();
}
``````markdown
/**
* <br>According to the database version and test case identifier, retrieves information from the database and writes it into the expected value in an Excel sheet.</br>
* @author Liu Zhi King
* @date 2018-04-20 18:01:04
* @param DataVersion
* @param ID
*/
public static void WriteExcelExpected(String DataVersion, int ID) {
List<Map<String, String>> данные = null;
данные = ExcelUtil.getInstance().readExcelAllData(TITLE_LINE_INDEX);
try {
if (данные != null) {
int i = ID;
Map<String, String> карта = данные.get(i);
String sql = карта.get("userId");
logger.info("Based on the query results from the database, the expected value writing starts [Expecting...]");
System.out.println("Based on the query results from the database, the expected value writing starts [Expecting...]");
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX - 1, TITLE_LINE_INDEX + i, "$id_Exp", "2");
String телефон_ожидаемый = Login_Controller.GetSqlResult(DataVersion, sql, "phone");
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX - 1, TITLE_LINE_INDEX + i, "phone_Exp", телефон_ожидаемый);
String рольId_ожидаемый = Login_Controller.GetSqlResult(DataVersion, sql, "roleId");
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX - 1, TITLE_LINE_INDEX + i, "roleId_Exp", рольId_ожидаемый);
}
} catch (Exception e) {
e.printStackTrace();
}
String role_name_exp = Login_Controller.GetSqlResult(DataVersion, sql, "roleName");
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX - 1, TITLE_LINE_INDEX + i, "role_name_exp", role_name_exp);
String sales_id_exp = Login_Controller.GetSqlResult(DataVersion, sql, "salesId");
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX - 1, TITLE_LINE_INDEX + i, "sales_id_exp", sales_id_exp);
String user_name_exp = Login_Controller.GetSqlResult(DataVersion, sql, "userName");
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX - 1, TITLE_LINE_INDEX + i, "user_name_exp", user_name_exp);
MobileApiToolsUtil
writeResult(TITLE_LINE_INDEX - 1, TITLE_LINE_INDEX + i, "identification_exp", "строка");
String photo_name_exp = Login_Controller.GetSqlResult(data_version, sql, "photoName");
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX - 1, TITLE_LINE_INDEX + i, "photo_name_exp", "http://10.10.11.136/" + photo_name_exp);
logger.info("Ожидаемое значение тестового примера успешно записано [OK]");
System.out.println("Ожидаемое значение тестового примера успешно записано [OK]");
System.out.println("=====================================================================");
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* По ID тестового примера выполняются запросы к API входа, получение JSON информации и запись результата в Excel
* @author Liu Zhi King
* @date 20 апреля 2018 г., 18:01:04
* @param ID
*/
public static void login(int id) throws Exception {
GetExcelInstance();
boolean arg_name = false;
List<Map<String, String>> data = null;
String api_url = ExcelUtil.getInstance().readExcelCell(1, 2);
String act = ExcelUtil.getInstance().readExcelCell(2, 2);
String method = ExcelUtil.getInstance().readExcelCell(3, 2);
arg_name = MobileApiToolsUtil.isArgEquals(4, 2, TITLE_LINE_INDEX);
if (api_url.equals("") || act.equals("") || method.equals("") || !arg_name) {
logger.error("Пожалуйста, проверьте правильность заполнения полей ApiUrl, Act, Method, ArgName в Excel...");
System.out.println("Проверьте правильность заполнения полей ApiUrl, Act, Method, ArgName в Excel... ");
System.exit(-1);
}
data = ExcelUtil.getInstance().readExcelAllData(TITLE_LINE_INDEX);
if (data != null) {
int i = ID;
```
// Получаем содержимое ячеек по названию колонок Excel
Map<String, String> map = data.get(i - 1); // Начинаем с первого тестового случая, 0 — это первый случай
String CaseID = map.get("CaseID");
String CaseName = map.get("CaseName");
String username = map.get("username");
String password = map.get("password");
// Записываем значение Run (результат выполнения теста), Y — выполнен
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "Run", "Y");
// Устанавливаем параметры запроса
Param = "username=" + username + "&password=" + password;
// Выполняем запрос к API и получаем массив UserInfo
Object[] UserInfo = Login_Controller.GetUserInfo(ID, ApiUrl, Param);
// Получаем StatusCode из массива UserInfo и записываем его
String code = (String) UserInfo[1];
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "StatusCode", code);
// Проверяем, равно ли StatusCode значению 999999, если да, то TestResult записывается как OK и цвет ячейки устанавливается зелёным, если нет, то записывается NG и цвет ячейки устанавливается красным, а также выводится сообщение об ошибке
if ("999999".equals(code)){
ExcelUtil.getInstance().setCellBackgroundColor(TITLE_LINE_INDEX, "StatusCode", TITLE_LINE_INDEX + i, 1);
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "TestResult", "OK");
ExcelUtil.getInstance().setCellBackgroundColor(TITLE_LINE_INDEX, "TestResult", TITLE_LINE_INDEX + i, 1);
// Получаем значение поля msg_Act из массива UserInfo и записываем его
msg_Act = (String) UserInfo[2];
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "msg_Act", msg_Act);
} else if ("400".equals(code)) {
ExcelUtil.getInstance().```markdown
writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "TestResult", "NG");
ExcelUtil.getInstance().setCellBackgroundColor(TITLE_LINE_INDEX, "TestResult", TITLE_LINE_INDEX + i, 0);
// Из массива UserInfo считываем сообщение и записываем его
String message = (String) UserInfo[0];
String newMessage = DecodeUnicodeUtil.decodeUnicode(message);
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "FailHint", newMessage);
msg_Act = null;
} else {
ExcelUtil.getInstance().setCellBackgroundColor(TITLE_LINE_INDEX, "StatusCode", TITLE_LINE_INDEX + i, 0);
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "TestResult", "NG");
ExcelUtil.getInstance().setCellBackgroundColor(TITLE_LINE_INDEX, "TestResult", TITLE_LINE_INDEX + i, 0);
// Из массива UserInfo считываем сообщение и записываем его
msg_Act = (String) UserInfo[2];
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "msg_Act", msg_Act);
}
// Запись времени выполнения
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "RunningTime", MobileApiToolsUtil.getDate());
// Из массива UserInfo считываем JSON-сообщение и записываем его после декодирования
String json = (String) UserInfo[0];
String newJson = DecodeUnicodeUtil.decodeUnicode(json);
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "Json", newJson);
if ("Успешно".equals(msg_Act)) {
// Из массива UserInfo считываем значение first_name_Act и записываем его
String first_name_Act = (String) UserInfo[3];
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "first_name_Act", first_name_Act);
// Из массива UserInfo считываем значение last_name_Act и записываем его
String last_name_Act = (String) UserInfo[4];
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "last_name_Act", last_name_Act);
// Из массива UserInfo считываем значение phone_Act и записываем его
String phone_Act = (String) UserInfo[5];
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "phone_Act", phone_Act);
```
```markdown
writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "phone_Act", phone_Act);
// Из массива UserInfo считываем значение email_Act и записываем
String email_Act = (String) UserInfo[6];
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "email_Act", email_Act);
// Из массива UserInfo считываем значение key_Act и записываем
String key_Act = (String) UserInfo[7];
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "key_Act", key_Act);
// Из массива UserInfo считываем значение date_joined_Act и записываем
String date_joined_Act = (String) UserInfo[8];
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "date_joined_Act", date_joined_Act);
// Из массива UserInfo считываем значение userphoto_Act и записываем
String userphoto_Act = (String) UserInfo[9];
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "userphoto_Act", userphoto_Act);
Reporter.log("Case ID: " + CaseID);
Reporter.log("Case Name: " + CaseName);
Reporter.log("Request URL: " + ApiUrl);
Reporter.log("Request Method: " + Method);
Reporter.log("Request Parameters: " + Param);
Reporter.log("Response Result: " + NewJson);
String first_name_Exp = map.get("first_name_Exp");
String last_name_Exp = map.get("last_name_Exp");
String phone_Exp = map.get("phone_Exp");
String email_Exp = map.get("email_Exp");
String key_Exp = map.get("key_Exp");
String date_joined_Exp = map.get("date_joined_Exp");
String userphoto_Exp = map.get("userphoto_Exp");
// Проверяем соответствие ожидаемых и фактических значений
checkEquals(first_name_Exp, first_name_Act, "first_name_Exp", "first_name_Act", ID);
checkEquals(last_name_Exp, last_name_Act, "last_name_Exp", "last_name_Act", ID);
```
```Также стоит отметить, что в данном примере использована IT-терминология, которая соответствует стандартам документации. Вместо использования таких терминов как "case" было решено использовать более понятное для русскоязычной аудитории слово "предложение". Однако, если требуется использование английских терминов, это также возможно.
```markdown
checkEquals(phone_Exp, phone_Act, "phone_Exp", "phone_Act", ID);
checkEquals(email_Exp, email_Act, "email_Exp", "email_Act", ID);
checkEquals(key_Exp, key_Act, "key_Exp", "key_Act", ID);
checkEquals(date_joined_Exp, date_joined_Act, "date_joined_Exp", "date_joined_Act", ID);
checkEquals(userphoto_Exp, userphoto_Act, "userphoto_Exp", "userphoto_Act", ID);
} else {
Reporter.log("Идентификатор тест-кейса: " + CaseID);
Reporter.log("Название тест-кейса: " + CaseName);
Reporter.log("Адрес запроса: " + ApiUrl);
Reporter.log("Метод запроса: " + Method);
Reporter.log("Параметры запроса: " + Param);
Reporter.log("Результат запроса: " + NewJson);
String msg_Exp = map.get("msg_Exp");
checkEquals(msg_Exp, msg_Act, "msg_Exp", "msg_Act", ID);
}
``` /**
* <br>Поиск тест-кейса по его идентификатору и проверка совпадения ожидаемого и фактического значений.<br>
* @author Liu Zhi King
* @date 2018-04-20 18:01:04
* @param ID
*/
public static void checkEquals(String expected, String actual, String expectedList, String actualList, int id) throws Exception {
int i = id;
try {
Assert.assertEquals(expected, actual);
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "TestResult", "OK");
ExcelUtil.getInstance().setCellBackgroundColor(TITLE_LINE_INDEX, "TestResult", TITLE_LINE_INDEX + i, 1);
Reporter.log("Результат тест-кейса: 〖" + expectedList.replace("_Exp", "") + "〗 => Ожидаемое значение: " + "【" + expected + "】, Фактическое значение: " + "【" + actual + "】");
System.out.println("Результат тест-кейса: 【" + expectedList.replace("_Exp", "") + "】 => Ожидаемое значение: " + "【" + expected + "】, Фактическое значение: " + "【" + actual + "】");
} catch (Error e) {
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "TestResult", "NG");
ExcelUtil.getInstance().setCellBackgroundColor(TITLE_LINE_INDEX, "TestResult", TITLE_LINE_INDEX + i, 0);
ExcelUtil.getInstance().writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "ErrorMessage", e.getMessage());
}
}
``````markdown
setCellBackgroundColor(TITLE_LINE_INDEX, ActualList, TITLE_LINE_INDEX + i, 3);
MobileApiToolsUtil.writeResult(TITLE_LINE_INDEX, TITLE_LINE_INDEX + i, "FailHint", "【" + ExpectedList + "】 и 【" + ActualList + "】 не совпадают");
Assert.fail("" + ExpectedList.replace("_Exp", "") + " => Ожидаемое 【" + Expected + "】 но найдено 【" + Actual + "】");
}
/**
* Поиск информации о тест-кейсе по его ID, вывод в консоль и запись в Excel
*
* @author Liu Zhi King
* @date 2018-04-20 18:01:04
* @param ID
*/
public static void GetCaseInfo(int ID) throws Exception {
GetExcelInstance();
List<Map<String, String>> data = null;
data = ExcelUtil.getInstance().readExcelAllData(TITLE_LINE_INDEX);
if (data != null) {
int i = ID;
Map<String, String> map = data.get(i - 1);
String CaseID = map.get("CaseID");
String CaseName = map.get("CaseName");
String msg_Exp = map.get("msg_Exp");
String first_name_Exp = map.get("first_name_Exp");
String last_name_Exp = map.get("last_name_Exp");
String phone_Exp = map.get("phone_Exp");
String email_Exp = map.get("email_Exp");
String key_Exp = map.get("key_Exp");
String date_joined_Exp = map.get("date_joined_Exp");
String userphoto_Exp = map.get("userphoto_Exp");
String msg_Act = map.get("msg_Act");
String first_name_Act = map.get("first_name_Act");
String last_name_Act = map.get("last_name_Act");
String phone_Act = map.get("phone_Act");
String email_Act = map.get("email_Act");
String key_Act = map.get("key_Act");
String date_joined_Act = map.get("date_joined_Act");
String userphoto_Act = map.get("userphoto_Act");
String StatusCode = map.get("StatusCode");
String TestResult = map.get("TestResult");
String FailHint = map.get("FailHint");
}
}
### Второй этап: создание тестового объекта сценария класса, например [Login.java]
Пакет TestCases;
Импорт org.testng.annotations.AfterTest;
Импорт org.testng.annotations.BeforeTest;
Импорт org.testng.annotations.Test;
``` ```java
public class Login {
private static final Logger logger = LoggerFactory.getLogger(Login.class);
@BeforeTest
public void setUp() {
// Настройка окружения перед запуском теста
}
@AfterTest
public void tearDown() {
// Очистка после завершения теста
}
@Test
public void testCase() {
int caseId = 0; // Уникальный идентификатор случая
String caseName = ""; // Название случая
String msgExp = ""; // Ожидаемое сообщение
String msgAct = ""; // Актуальное сообщение
String firstNameExp = ""; // Ожидаемое имя
String firstNameAct = ""; // Актуальное имя
String lastNameExp = ""; // Ожидаемая фамилия
String lastNameAct = ""; // Актуальная фамилия
String phoneExp = ""; // Ожидаемый номер телефона
String phoneAct = ""; // Актуальный номер телефона
String emailExp = ""; // Ожидаемый адрес электронной почты
String emailAct = ""; // Актуальный адрес электронной почты
String keyExp = ""; // Ожидаемый ключ
String keyAct = ""; // Актуальный ключ
String dateJoinedExp = ""; // Ожидаемая дата присоединения
String dateJoinedAct = ""; // Актуальная дата присоединения
String userPhotoExp = ""; // Ожидаемое изображение пользователя
String userPhotoAct = ""; // Актуальное изображение пользователя
int statusCode = 0; // Код состояния
boolean testResult = false; // Результат теста
String failHint = ""; // Подсказка при ошибке
}
```
```markdown
testng.annotations.Test;
import com.jmoney.luckeylink.handler.Login_Handler;
public class Login {
@BeforeTest
private void setUp() throws Exception {
Login_Handler.InitializeExcelData();
}
// Вывод лога
logger.info("CaseID: " + CaseID + ", CaseName: " + CaseName +
", msg_Exp: " + msg_Exp + ", msg_Act: " + msg_Act +
", first_name_Exp: " + first_name_Exp + ", first_name_Act: " + first_name_Act +
", last_name_Exp: " + last_name_Exp + ", last_name_Act: " + last_name_Act +
", phone_Exp: " + phone_Exp + ", phone_Act: " + phone_Act +
", email_Exp: " + email_Exp + ", email_Act: " + email_Act +
", key_Exp: " + key_Exp + ", key_Act: " + key_Act +
", date_joined_Exp: " + date_joined_Exp + ", date_joined_Act: " + date_joined_Act +
", userphoto_Exp: " + userphoto_Exp + ", userphoto_Act: " + userphoto_Act +
", StatusCode: " + StatusCode + ", TestResult: " + TestResult + ", FailHint: " + FailHint + "");
logger.info("==================================================================");
System.out.println("CaseID: " + CaseID + ", CaseName: " + CaseName +
", msg_Exp: " + msg_Exp + ", msg_Act: " + msg_Act +
", first_name_Exp: " + first_name_Exp + ", first_name_Act: " + first_name_Act +
", last_name_Exp: " + last_name_Exp + ", last_name_Act: " + last_name_Act +
", phone_Exp: " + phone_Exp + ", phone_Act: " + phone_Act +
", email_Exp: " + email_Exp + ", email_Act: " + email_Act +
", key_Exp: " + key_Exp + ", key_Act: " + key_Act +
", date_joined_Exp: " + date_joined_Exp + ", date_joined_Act: " + date_joined_Act +
", userphoto_Exp: " + userphoto_Exp + ", userphoto_Act: " + userphoto_Act +
", StatusCode: " + StatusCode + ", TestResult: " + TestResult + ", FailHint: " + FailHint + "");
System.out.println("==================================================================");
}
```
```markdown
}
@Test
public void Case1() throws Exception {
Login_Handler.Login(1);
}
@Test
public void Case2() throws Exception {
Login_Handler.Login(2);
}
@Test
public void Case3() throws Exception {
Login_Handler.Login(3);
}
@Test
public void Case4() throws Exception {
Login_Handler.Login(4);
}
@Test
public void Case5() throws Exception {
Login_Handler.Login(5);
}
@Test
public void Case6() throws Exception {
Login_Handler.Login(6);
}
@Test
public void Case7() throws Exception {
Login_Handler.Login(7);
}
@AfterTest
public void TearDown() throws Exception {
Login_Handler.GetCaseInfo(1);
Login_Handler.GetCaseInfo(2);
Login_Handler.GetCaseInfo(3);
Login_Handler.GetCaseInfo(4);
Login_Handler.GetCaseInfo(5);
Login_Handler.GetCaseInfo(6);
Login_Handler.GetCaseInfo(7);
}
}


```#### Приведён выше пример одного тестового случая. Определение параметров для связанных интерфейсов выполняется в соответствии с конкретной документацией интерфейса. Это очень простой процесс, аналогичный написанию тестовых случаев.
- Для получения подробностей о методах написания скриптов обратитесь к следующему источнику: [https://pan.baidu.com/s/1MnC38bdPKpyFu_8nsjdMsA](https://pan.baidu.com/s/1MnC38bdPKpyFu_8nsjdMsA)
- Для получения официального руководства по использованию обратитесь к следующему источнику: [https://testerhome.com/topics/7060](https://testerhome.com/topics/7060)
---
### Третье. Конфигурация тестовых случаев Rest Assured:
public static void GetExcelInstance() {
logger.info(Login_Handler.class);
System.out.println(Login_Handler.class);
ExcelUtil.getInstance().setFilePath("src/test/java/TestCasexls/JMoney.Luckeylink.Api.xlsm");
ExcelUtil.getInstance().setSheetName("Login");
}
- При выполнении тестов требуется указание пути к файлу Excel с тестовыми случаями и имени листа. В данном случае используется JMoney.Luckeylink.Api.---
### 4. Выполнение тест-кейсов:
- После того как вы создали соответствующие обработчики тестовых объектов класса [LoginHandler.java] и тестовый сценарий класса [Login.java], выберите в проекте Eclipse файл Login.java правой кнопкой мыши и запустите его через TestNG

---
### 5. Отчет о тестировании:
- Отчет о тестировании представлен в двух вариациях: один — это отчет TestngReport, который входит в состав TestNG, второй — это отчет, созданный с помощью ExtentReports, который более эстетичен
#### [TestngReport](https://testerhome.com/uploads/photo/2018/8da0567e-881e-4e01-af90-3928b1456d8e.png!large)
```xml
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Web-backend-API automation testing" parallel="false" configfailurepolicy="continue">
<test name="User login API" junit="false" verbose="3" parallel="false" thread-count="5" annotations="javadoc" time-out="6000000" enabled="true" skipfailedinvocationcounts="true" preserve-order="true" allow-return-values="true">
<classes>
<class name="TestCases.Login">
<methods>
<include name="case1" />
<include name="case2" />
<include name="case3" />
<include name="case4" />
<include name="case5" />
<include name="case6" />
<include name="case7" />
<exclude name="" />
</methods>
</class>
</classes>
</test>
<!-- -------------------------------------------- Разделитель ------------------------------------------------ -->
<!-- Включенные слушатели -->
<listeners>```markdown
<listeners>
<listener class-name="org.uncommons.reportng.HTMLReporter"></listener>
<listener class-name="org.uncommons.reportng.JUnitXMLReporter"></listener>
</listeners>
```xml
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" verbose="1" preserve-order="true" parallel="false">
<suite-files>
<suite-file path="Login.xml"></suite-file>
</suite-files>
</suite>
```
<listeners>
<listener class-name="com.jmoney.luckeylink.service.ExtentReportGenerateService"></listener>
</listeners>
<!-- C:\Windows\System32\drivers\etc
151.139.237.11 cdn.rawgit.com -->
</suite>

- Второй отчет о тестировании требует использования прокси-сервера для нормального отображения; в противном случае страница будет содержать хаотичные символы, так как это иностранное содержание.
- Либо добавьте в конец файла hosts (C:\Windows\System32\drivers\etc) следующий адрес: 151.139.237.11 cdn.rawgit.com
---
### Шесть. Непрерывная интеграция Jenkins:


- Установка среды Jenkins, подробнее см.: https://blog.csdn.net/wuxuehong0306/article/details/50016547
- Настройка проекта автоматической непрерывной интеграции Jenkins позволяет автоматически запускать скрипты на удаленном сервере (конфигурация, сборка, пакетирование), отправлять электронные сообщения с отчетами о тестировании и т. д.
---
### Семь. Благодарность
```#### Если вам понравился этот фреймворк, вы можете сделать пожертвование, чтобы мотивировать меня продолжать работу.
**Большое спасибо за то, что вы уделили время для чтения данного материала. Желаю вам приятного времяпровождения при записи, чтении и обсуждении материалов здесь.**
**Приглашаю вас оставлять свои отзывы и вопросы, а также обращаться ко мне лично или присоединяться к группе для обсуждения.**
Автор: [@Лiu Zhi King](http://shang.qq.com/email/stop/email_stop.html?qq=1306086303&sig=a1c657365db7e82805ea4b2351081fc3ebcde159f8ae49b1&tttt=1)
QQ: 1306086303
Email: hagyao520@163.com
> Официальная группа QQ для общения по теме "Software Testing and Development": 126325132
<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=346d11a1a76d05086cd48bc8249126f514248479b50f96288189ab5ae0ca7ba5"><img border="0" src="//pub.idqqimg.com/wpa/images/group.png" alt="软件测试开发交流群" title="软件测试开发交流群"></a>
```
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )