Перейти к содержимому

Фотография

Тестирование взаимодействия с БД (JAVA)


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 6

#1 Petrov.Sergey

Petrov.Sergey

    Опытный участник

  • Members
  • PipPipPipPip
  • 446 сообщений
  • ФИО:Petrov Sergey
  • Город:МО, Лобня


Отправлено 26 сентября 2013 - 12:45

Есть табличка в БД.
Есть внешнее приложение, которое загружает данные из XML в БД по определённым правилам (которых сотни).
XML не гарантирует вставку данных в таблицу (если данные не изменялись, инсёрт не происходит). Апдейтов нет: либо инсёрт, либо ничего. На самом деле апдейты есть, но это совершенно не проблема. Будем считать, что их нет.

Вопрос: как бы Вы предложили проверять корректность переноса данных?

Ищу решение, которое будет отлично от моего и будет использовать стандартный фреймворк (тот же JUnit, например, или TestNG).

Моё решение: написал свой фреймворк. Создал "модельный" класс Table.java, олицетворяющий запись в БД.
Класс Table содержит:
  • приватный список полей, по названию (для удобства) и количеству полностью совпадающий со списком полей в интересующей таблице в БД
  • публичные методы геттеры и сеттеры (на всякий случай)
  • конструктор, принимающий на вход кусок XML, который матчится в базу, и заполняющий объект в соответствии с тем, что должно лежать в БД.

Сам по XML формирую объект Table table = new Table(<кусок XML в виде объекта>);
Далее вызываю предварительно написанный метод CheckDB.checkTable(table, true), принимающий на вход проверяемый объект и булевскую переменную, символизирующую необходимость существования этой записи (должна ли она вообще появиться), который внутри себя выполняет:
sQuery = "select ....."; // Гарантия, что в случае обнаружения найдётся именно моя запись = 100% (селект грамотный)
	String[][] resultTable = db.getDataAsTable(sQuery); // первая строка в массиве - имена полей в результате запроса

	if (need) {
		if (resultTable.length > 1) {
			assertString(result[0][0], table.getField1(), result[1][0]); // ассёрт самописный
			assertString(result[0][1], table.getField2(), result[1][1]);
			...........................
			assertString(result[0][N], table.getFieldN(), result[1][N]);
			if (resultTable.length > 2) {
				commonLog("Есть лишние записи! <=== FAIL!!!");
				for (int i = 2; i < resultTable.length; i++) {
					commonLog(Arrays.asList(resultTable[i]).toString());
				}
			}
		} else {
			commonLog("Запись отсутствует <=== FAIL!!!");
		}
	} else {
		if (resultTable.length > 1) {
			commonLog("Запись не должна была появиться! <=== FAIL!!!");
			commonLog(Arrays.asList(resultTable[1]).toString());
		} else {
			commonLog("Запись отсутствует (CORRECT)");
		}
	}
Каждое несоответствие в ассёрте - это +1 фэйл.
С одной стороны, вроде бы, хорошо. Но это самописный фреймворк, который формирует также самописный отчёт в текстовом файлике. Не хочется тратить время на велосипед - созрел для использования стандартной JUnit-овской или ещё какой-либо шаблонной, другими написанной и откатанной отчётности.

С другой стороны, когда начинаю думать о JUnit, понимаю, что там +1 фейл - это весь тестовый класс-файл.
Соответственно, если мне надо проверить N полей и получить +K фейлов, мне нужно писать N одинаковых тестовых класс-файлов с проверкой одного соответствующего поля в БД? Да я сдохну! Плюс копипаст - это неправильно. В общем, эта идея мне явно не по душе!

Поделитесь своим опытом - что посоветуете? Как Вы проверяете корректность данных в БД?
Уверен, должны быть способы/технологии, о которых я ещё не знаю.
  • 0
Форум читаю набегами. По возникшим вопросам можно в скайп (в профиле).

#2 VitalyD

VitalyD

    Опытный участник

  • Members
  • PipPipPipPip
  • 285 сообщений
  • Город:Санкт-Петербург

Отправлено 26 сентября 2013 - 13:22

Посмотрите на датапровайдер в testNG:
http://testng.org/do...s-dataproviders

Я когда то делал что то похожее с помощью него.
В дата провайдере считывался эксель файл и данные из строк экселя передавались в тестовый метод тем самым формируя тест.
Сколько строк столько и тестов.

Навскидку что то подобное можно и в вашем случае сделать...
  • 0

#3 Petrov.Sergey

Petrov.Sergey

    Опытный участник

  • Members
  • PipPipPipPip
  • 446 сообщений
  • ФИО:Petrov Sergey
  • Город:МО, Лобня


Отправлено 26 сентября 2013 - 13:48

Посмотрите на датапровайдер в testNG:
http://testng.org/do...s-dataproviders

Я когда то делал что то похожее с помощью него.
В дата провайдере считывался эксель файл и данные из строк экселя передавались в тестовый метод тем самым формируя тест.
Сколько строк столько и тестов.

Навскидку что то подобное можно и в вашем случае сделать...

Посмотрел, на датапровайдер.
Понимаете, "сколько строк - столько и тестов" - это не совсем то, что мне нужно.

Мне нужно "сколько полей - столько и тестов", потому что это реально "проверка содержимого одного поля".
Разница между записью, в которой только одно поле некорректное, и записью, в которой 10 полей некорректные, очень большая. По крайней мере, для меня и для разработчика, т.к. в первом случае объяснение одно, а во втором - несколько!
И один результат "FAIL" на всю запись совершенно не репрезентабелен.

Скажем так, в моей реализации мне не нравится только отчётность.
Совершенствование фреймворка с переходом на Spring делать не хочу, т.к. там в дебри залезу + Spring требует EJB 2.0, с которыми я ни разу не работал, по причине того, что в тестировании они вообще не нужны.
  • 0
Форум читаю набегами. По возникшим вопросам можно в скайп (в профиле).

#4 Petrov.Sergey

Petrov.Sergey

    Опытный участник

  • Members
  • PipPipPipPip
  • 446 сообщений
  • ФИО:Petrov Sergey
  • Город:МО, Лобня


Отправлено 26 сентября 2013 - 13:59

Знатоки JUnit || TestNG, а можно ли в этих фреймворках сделать что-то такое?
public static String[][] resultTable = new String[][];

@BeforeSuite
public void prepareMethod() {
    ....
    resultTable = db.getDataAsTable(sQuery);
}

@Test
public void launcher() {
    CheckDB.test(param1, field1); // вызов класса-теста, метод test которого описан чуть ниже.
    CheckDB.test(param2, field2);
    .....
    CheckDB.test(paramN, fieldN);
}

@AfterTest
public void epilog() {
    ....
}

@Test
public void test(String param, int field) {
    assertEquals(param, resultTable[1][field]); // resultTable импортируется из вызывающего класса, или можно просто передать его на вход в качестве параметра тестового метода
}

  • 0
Форум читаю набегами. По возникшим вопросам можно в скайп (в профиле).

#5 Petrov.Sergey

Petrov.Sergey

    Опытный участник

  • Members
  • PipPipPipPip
  • 446 сообщений
  • ФИО:Petrov Sergey
  • Город:МО, Лобня


Отправлено 26 сентября 2013 - 14:11

Нашёл.
В TestNG в качестве "сборщика" может выступать @Factory
  • 0
Форум читаю набегами. По возникшим вопросам можно в скайп (в профиле).

#6 VitalyD

VitalyD

    Опытный участник

  • Members
  • PipPipPipPip
  • 285 сообщений
  • Город:Санкт-Петербург

Отправлено 26 сентября 2013 - 14:20

Да, вы меня опередили. как раз фактори хотел предложить...

Ну и я не понял почему нельзя транспонировать массив, то есть как-то так это бы выглядело:


    @DataProvider(name = "dbData")
    public static  Object[][] getResultTable() {
        String[][] resultTable = db.getDataAsTable(sQuery);
   
        //транспонировать массив
        return resultTableAfterTrans;
    }

    @Test(dataProvider = "dbData")
    @Test(priority = 1)
    public void createMuseum(String fieldName, String fieldValue) {

        assertEquals(testValue, table.getFieldByName(fieldName));
    }

Проверки на то что не больше двух строк и остальные из вашего примера вставить либо отдельным вторым тестом или в датапровайдер или чуть усложнить то что выдает датапровайдер...
  • 0

#7 Petrov.Sergey

Petrov.Sergey

    Опытный участник

  • Members
  • PipPipPipPip
  • 446 сообщений
  • ФИО:Petrov Sergey
  • Город:МО, Лобня


Отправлено 26 сентября 2013 - 14:33

Да, вы меня опередили. как раз фактори хотел предложить...

Ну и я не понял почему нельзя транспонировать массив, то есть как-то так это бы выглядело:


    @DataProvider(name = "dbData")
    public static  Object[][] getResultTable() {
        String[][] resultTable = db.getDataAsTable(sQuery);
   
        //транспонировать массив
        return resultTableAfterTrans;
    }

    @Test(dataProvider = "dbData")
    @Test(priority = 1)
    public void createMuseum(String fieldName, String fieldValue) {

        assertEquals(testValue, table.getFieldByName(fieldName));
    }

Проверки на то что не больше двух строк и остальные из вашего примера вставить либо отдельным вторым тестом или в датапровайдер или чуть усложнить то что выдает датапровайдер...


Ну, в общем, я понял: TestNG в принципе, удовлетворяет моим потребностям, правда, с неким извращением. Поковыряться придётся для реализации и дальнейшего импорта.
Спасибо большое!
  • 0
Форум читаю набегами. По возникшим вопросам можно в скайп (в профиле).


Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных