Форум программистов, компьютерный форум, киберфорум
Python: Web
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
 Аватар для tramp_1-3
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454

Правильно ли я тестирую приложение?

17.06.2015, 16:10. Показов 1267. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Первое моё TDD приложение. Тест тоже отрабатывает верно. Если в моделях я уверен, то насчет тестов нет. Мои вопросы:
1) Нужно при каждом тесте создавать данные и сохранять их, как я здесь сделал?
2) Не слишком ли тестовые классы взаимосвязаны? Мне пришлось создавать статические конструкторы, потому что тестирование проекта без создания остальных объектов было бы невозможно.
3) Соблюдены ли общие правила создания тестов?
4) Нужно ли вручную уничтожать созданные в ходе тестов объекты?

Единственный тест расположен в функции test_get_root_tasks
Тесты
Кликните здесь для просмотра всего текста
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from django.test import TestCase
from django.utils import timezone
from .models import Task, Project, Chief
 
class TaskMethodTests(TestCase):
    @staticmethod
    def create_test_tasks():
        task_array = []
        for i in range(0, 10):
            task_array.append(Task.objects.create(name='task ' + str(i), description='wow, task ' + str(i) + '!',
                                                  start_date=timezone.now(), end_date=timezone.now()))
        return task_array
 
    @staticmethod
    def destroy_test_tasks(task_array):
        for t in task_array:
            t.delete()
 
 
class ProjectMethodTests(TestCase):
    @staticmethod
    def create_test_project():
        return Project.objects.create(name='test proj', description="wow, such test",
                                      start_date=timezone.now(), end_date=timezone.now(),
                                      chief=ChiefMethodTests.create_test_chief())
 
    def test_get_root_tasks(self):
        project = ProjectMethodTests.create_test_project()
        task_array = TaskMethodTests.create_test_tasks()
 
        # подчинить все задания первому заданию
        for i in range(1, 10):
            task_array[i].parent_task = task_array[0]
        # присвоить все задания проекту
        for i in range(0, 10):
            task_array[i].project = project
 
        root_tasks = project.get_root_tasks()
        #проверить, вернулось ли что-нибудь вообще
        self.assertNotEqual(root_tasks.count(), 0)
 
        for task in root_tasks:
            self.assertEqual(task.parent_task, None)
 
 
class ChiefMethodTests(TestCase):
    @staticmethod
    def create_test_chief():
        return Chief.objects.create(surname="test chief", dob=timezone.now(),
                                    email="")


Модели
Кликните здесь для просмотра всего текста
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
from django.db import models
 
# Create your models here.
 
 
class Skill(models.Model):
    name = models.CharField(max_length=20)
    description = models.TextField(max_length=200)
 
    def __str__(self):
        return self.name
 
 
class Faculty(models.Model):
    name = models.CharField(max_length=20)
    description = models.TextField(max_length=200)
 
    def __str__(self):
        return self.name
 
 
class Major(models.Model):
    name = models.CharField(max_length=20)
    description = models.TextField(max_length=200)
 
    faculty = models.ForeignKey(Faculty)
 
    def __str__(self):
        return self.name
 
 
class Person(models.Model):
    personal_name = models.CharField(max_length=40)
    patronymic_name = models.CharField(max_length=40)
    surname = models.CharField(max_length=40)
    dob = models.DateField()
    email = models.EmailField()
 
    class Meta:
        abstract = True
 
    def __str__(self):
        return self.surname + " " + self.personal_name + " " + self.patronymic_name
 
 
class Student(Person):
    faculty = models.ForeignKey(Faculty)
    major = models.ForeignKey(Major)
    skills = models.ManyToManyField(Skill)
 
 
class Chief(Person):
    additional_info = models.TextField(max_length=200)
 
 
class Project(models.Model):
    name = models.CharField(max_length=30)
    description = models.TextField(max_length=200)
    start_date = models.DateField()
    end_date = models.DateField()
 
    students = models.ManyToManyField(Student)
    chief = models.ForeignKey(Chief)
 
    def __str__(self):
        return self.name
 
    def get_root_tasks(self):
        return Task.objects.filter(pk=self.pk, parent_task__isnull=True)
 
 
class Task(models.Model):
    name = models.CharField(max_length=20)
    description = models.TextField(max_length=200, blank=True)
    project = models.ForeignKey(Project, default=0)
    start_date = models.DateField()
    end_date = models.DateField()
 
    parent_task = models.ForeignKey('self', null=True, blank=True)
 
    def __str__(self):
        return self.name
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
17.06.2015, 16:10
Ответы с готовыми решениями:

Создание приложение типа Messenger. Как правильно создать такое приложение?
Доброго времени суток. Вот мне нужно написать приложение типа Messenger на технологии WinForms или WPF. Кол-во пользователей неопределено....

Создание приложение типа Messenger. Как правильно создать такое приложение?
Доброго времени суток. Вот мне нужно написать приложение типа Messenger на технологии WinForms или WPF. Кол-во пользователей неопределено....

Тестирую скрипт
Всем привет! Делаю скрипт Голосования, сегодня кое как сделал уникальное голосования(по IP-адресу). Веб-сервер локальный т. е. 127.0.0.1...

11
 Аватар для ilnurgi
141 / 141 / 38
Регистрация: 20.02.2012
Сообщений: 597
18.06.2015, 09:14
Лучший ответ Сообщение было отмечено tramp_1-3 как решение

Решение

лично я не понял смысл статических методов.

у TestCase есть метод setUp() в котором вы создаете какие то начальные данные, если надо. данные в БД и другое.
далее в TestCase добавляете методы test_имя_теста() который и выполняет ваш тест.

setUp выполнится 1 раз для TestCase, и все его данные будут доступны в каждом тесте. Но данные самих тестов не будут доступны в других тестах.

Речь именно о тестовых методах, а не о TestCase.

Данные TestCase также сама удаляет, после каждого теста, и после TestCase.

Добавлено через 12 минут
что-то типа такого

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from django.test import TestCase
from django.utils import timezone
from .models import Task, Project, Chief
 
class MyTest(TestCase):
 
    def setUp(self):
 
        now = timezone.now()
 
        self.chief = ChiefMethodTests.objects.create(
            surname="test chief", 
            dob=now,
            email="")
 
        self.project = Project.objects.create(
            name='test proj', 
            description="wow, such test",
            start_date=now, 
            end_date=now,
            chief=self.chief)
 
        self.root_task = Task.objects.create(
                name='task 0',
                description='wow, task 0!',
                start_date=now, 
                end_date=now,
                project=self.project) 
 
        self.task_array = [
            Task.objects.create(
                name='task {0}'.format(i), 
                description='wow, task {0}!'.format(i),
                start_date=now, 
                end_date=now,
                project=self.project,
                parent_task=self.root_task) 
            for i in xrange(1, 10)]
 
    def test_get_root_tasks(self):
 
        root_tasks = self.project.get_root_tasks()
 
        #проверить, вернулось ли что-нибудь вообще
        self.assertNotEqual(root_tasks.count(), 0)
 
        for task in root_tasks:
            self.assertEqual(task.parent_task, None)
1
 Аватар для tramp_1-3
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
18.06.2015, 10:45  [ТС]
ilnurgi, в руководстве джанго не встречал такого, спасибо большое.
0
 Аватар для ilnurgi
141 / 141 / 38
Регистрация: 20.02.2012
Сообщений: 597
18.06.2015, 10:46
как так. какое руководство смотрите?
0
 Аватар для tramp_1-3
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
18.06.2015, 10:47  [ТС]
ilnurgi, https://docs.djangoproject.com... utorial05/
0
 Аватар для ilnurgi
141 / 141 / 38
Регистрация: 20.02.2012
Сообщений: 597
18.06.2015, 10:47
не забудьте ещё https://docs.djangoproject.com... /overview/ глянуть
1
 Аватар для tramp_1-3
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
18.06.2015, 11:42  [ТС]
ilnurgi, а если я решу добавить ещё тестов, допустим для других классов, мне создавать новый тестовый класс, или можно пихать методы в уже существующий?
0
 Аватар для ilnurgi
141 / 141 / 38
Регистрация: 20.02.2012
Сообщений: 597
18.06.2015, 11:45
ну тут надо смотреть, и решать тебе, можно сделать 1 толстый тесткейс, можно кучу тесткейсов с 1 тестом.

надо определиться что именно ты тестишь, и самому определить, стоит разделять или нет.

если ты тестишь какую то модель, то лучше на каждую модель по тесткейсу да.

и больно не увлекаться наследованием тесткейсов.
0
 Аватар для tramp_1-3
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
18.06.2015, 11:49  [ТС]
ilnurgi, дело в том, что у меня объекты тесно связаны. невозможно создать проект, не создав подчиненных объектов. видимо, у меня нет выбора, кроме как тестировать всё в куче.
0
 Аватар для ilnurgi
141 / 141 / 38
Регистрация: 20.02.2012
Сообщений: 597
18.06.2015, 12:24
все в куче не хорошо. тест не должен быть большим и сложным.

вы тестируете 1 модель, для неё нужны другие данные, создавайте их в сетапе. я как вам показал
0
 Аватар для tramp_1-3
16 / 16 / 1
Регистрация: 13.10.2012
Сообщений: 454
18.06.2015, 12:32  [ТС]
ilnurgi, столько повторяющихся данных? тогда уже в статическую функцию выделить что-ли, которая в сетап будет возвращать вот это всё.
0
 Аватар для ilnurgi
141 / 141 / 38
Регистрация: 20.02.2012
Сообщений: 597
18.06.2015, 12:38
Лучший ответ Сообщение было отмечено tramp_1-3 как решение

Решение

ну можно и так. возможно можно обойтитсь 1 тесткейсом, с одним сетапом и с несколькими методами. если тест для одного приложения.

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

тесты должны быть минимально простыми.

и не надо писать 1 тест (непутать с тесткейсом) который много чего тетсирует

Добавлено через 53 секунды
раз сетап у вас повторяется, то можно использовать наследование, либо, все впихнуть в одном тесткейсе
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.06.2015, 12:38
Помогаю со студенческими работами здесь

Тестирую программу - нужны задания
Здравствуйте. Создана софтинка, которая может считать в большом диапазоне и с большой точностью. Сразу скажу - это не binary128, не...

Тестирую уцененный Asus Fonepad 8
Добрый день. В общем случайно наткнулся в магазине на уцененный Fonepad 8 (FE380). И я повелся на цену : 7000. В качестве причины...

Тестирую 3d игру Tactics XNA3.1
Тестирую 3d игру Tactics XNA3.1

Тестирую работоспособность сайта и есть неудача
Когда пытаюсь зарегаться или войти пишет: Warning: Cannot modify header information - headers already sent by (output started at...

На сервере все работает, а когда на PWS тестирую - ошибка!
На сервере все работает, а когда на PWS у себя на машине тестирую - ошибка! Response object error 'ASP 0156 : 80004005' Header...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru