Как написать программу для теста

0 / 0 / 0

Регистрация: 31.01.2012

Сообщений: 9

1

Как написать программу для тестирования знаний

31.01.2012, 22:34. Показов 31709. Ответов 9


Система тестирования знаний.
Дан текстовый файл с вопросами и верными ответами. Ввести Ф.И.О тестируемого(или выбрать из готового списка). Предусмотреть кнопки на окне программыили пункты меню в текст. режиме: 1,2,3 и т.д. с вариантами ответов. В конце процент верных ответов.
P.S. не могу понять форма это или консольное приложение.
P.S.S буду очень благодарен за выделенное вами время данному вопросу

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



179 / 180 / 54

Регистрация: 01.06.2011

Сообщений: 507

31.01.2012, 22:46

2

Собственно по первому P.S. — это будет то, что Вам хочется (удобнее форму).
Остальное не понял. Где вопрос? Вам программу написать?



0



0 / 0 / 0

Регистрация: 31.01.2012

Сообщений: 9

01.02.2012, 00:25

 [ТС]

3

Если не затруднит, то да, это было бы просто шикарно



0



0 / 0 / 0

Регистрация: 31.01.2012

Сообщений: 9

01.02.2012, 03:14

 [ТС]

4

Ну я надеюсь, что и тут добрые люди имеются



0



717 / 708 / 168

Регистрация: 15.06.2011

Сообщений: 1,704

01.02.2012, 17:42

5

Добрые люди найдуться, но проект вам тут никто делать не будет

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

1) Ваш текст говорит сам за себя:

Предусмотреть кнопки на окне программыили пункты меню в текст.

2) Ждем ваших вопросов)))



1



Deathroll1

0 / 0 / 0

Регистрация: 31.01.2012

Сообщений: 9

03.02.2012, 10:58

 [ТС]

6

что то умудлился скопипастить… и посоветоваться с товарищами… Получил следующее:

C#
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace Тестилка
{
    public partial class Form1 : Form
    {
        string fpath;   //путь файлу к теста
        string fname;   //файл теста
 
        //XmlReader обеспечивает чтение данных xml-файла
        System.Xml.XmlReader xmlReader;
 
        string qw;  //Вопрос
 
        //Варианты ответа
        string[] answ = new string[3];
       
        string pic; //путь к файлу иллюстрации
 
        int right;  //правильный ответ
        int otv;    //выбранный ответ
        int n;      //количество правильных ответов
        int nv;     //общее количетсво вопросов
        int mode;   //состоянине программы
                    //0 - начало работы;
                    //1 - тестирования;
                    //2 - завершение работы
 
        //Конструктор формы
        //(см. также Program.cs)
        public Form1(string[] args)
        {
             InitializeComponent();
 
            radioButton1.Visible = false;
            radioButton2.Visible = false;
            radioButton3.Visible = false;
            radioButton4.Visible = false;
            pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
            fname = "spb.xml";
            try
            {
                //Прочитать xml-файл
                xmlReader =
                    new System.Xml.XmlTextReader(/*fpath + */fname);
                xmlReader.Read();
 
                mode = 0;
                n = 0;
 
                //Загрузить и показать заголовок текста
                this.showHead();
 
                //Загрузить и показать описание текста
                this.showDescription();
            }
            catch (Exception exc)
            {
                label1.Text = "Ошибка доступа к файлу " +
                    exc + fpath + fname;
 
                MessageBox.Show("Ошибка доступа к файлу.n" +
                    fpath + fname + "n",
                    "Экзаменатор",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
 
                mode = 2;
            }
        }
        //Выводит название (заголовок) текста
        private void showHead()
        {
            //ищем узел <head>
            do xmlReader.Read();
            while (xmlReader.Name != "head");
 
            //считываем заголовок
            xmlReader.Read();
 
            //вывести название текста в заголовк окна
            this.Text = xmlReader.Value;
 
            //выходим из узла <head>
            xmlReader.Read();
        }
        private void showDescription()
        {
            //ищем узел <Description>
            do
                xmlReader.Read();
            while (xmlReader.Name != "description");
 
            //считываем описание теста
            xmlReader.Read();
 
            //выводим описание теста
            label1.Text = xmlReader.Value;
 
            //выходим из узла <description>
 
            //ищем узел вопросов <qw>
            do
                xmlReader.Read();
            while (xmlReader.Name != "qw");
 
            //входим внутрь узла
            xmlReader.Read();
        }
        //читает вопрос из файла теста
        private Boolean getQw()
        {
            //считываем тег <q>
            xmlReader.Read();
 
            if (xmlReader.Name == "q")
            {
                //здесь прочитан тег <q>,
                //атрибут text которого содержит вопрос
                //а атрибут src - имя файла иллюстрации
 
                //извлекаем значение атрибутов
                qw = xmlReader.GetAttribute("text");
                pic = xmlReader.GetAttribute("src");
 
//                if (!pic.Equals(string.Empty)) pic = fpath + pic;
 
                //входим внутрь узла
                xmlReader.Read();
                int i = 0;
 
                //считываем данныем из вопроса <q>
                while (xmlReader.Name != "q")
                {
                    xmlReader.Read();
 
                    //вырианты ответа
                    if (xmlReader.Name == "a")
                    {
                        //если есть атрибут right, то это
                        //правильный ответ
                        if (xmlReader.GetAttribute("right") == "yes")
                        right = i;
 
                        //считываем вариант ответа
                        xmlReader.Read();
                        if (i < 3) answ[i] = xmlReader.Value;
 
                        //выходим из узла <a>
                        xmlReader.Read();
 
                        i++;
                    }
                }
                //выходим из узла вопроса <q>
                xmlReader.Read();
 
                return true;
            }
            //если считанный тег не <q>
            else
                return false;
        }
        private void showQw()
        {
            //выводим вопрос
            label1.Text = qw;
 
            //иллюстрация
            if (pic.Length != 0)
            {
                try
                {
//                    pictureBox1.Image = new Bitmap(pic);
 
                    pictureBox1.Visible = true;
 
                    radioButton1.Top = pictureBox1.Bottom + 16;
                }
                catch
                {
                    if (pictureBox1.Visible)
                        pictureBox1.Visible = false;
 
                    label1.Text +=
                        "nnnОшибка доступа к файлу " + pic + ".";
 
                    radioButton1.Top = label1.Bottom + 8;
                }
            }
            else
            {
                if (pictureBox1.Visible)
                    pictureBox1.Visible = false;
                radioButton1.Top = label1.Bottom;
            }
            //Показать варианты ответа
            radioButton1.Text = answ[0];
            radioButton2.Top = radioButton1.Top + 24; ;
            radioButton2.Text = answ[1];
            radioButton3.Top = radioButton2.Top + 24; ;
            radioButton3.Text = answ[2];
 
            radioButton4.Checked = true;
            button1.Enabled = false;
        }
               
        //Щелчок на кнопке выбора ответа
        //функция обрабатывает событие click
        //компонентов radioButton1 - radioButton3
 
        private void Form1_Load(object sender, EventArgs e)
        {
 
        }
        //Щелчок на кнопке ОК
        private void button1_Click(object sender, EventArgs e)
        {
            int j = 1;
            pictureBox1.ImageLocation = String.Format("{0}{1}", j, ".jpg");
            switch (mode)
            {
                case 0:     //начало работы
                    radioButton1.Visible = true;
                    radioButton2.Visible = true;
                    radioButton3.Visible = true;
 
                    this.getQw();
                    this.showQw();
 
                    mode = 1;
 
                    button1.Enabled = false;
                    radioButton4.Checked = true;
                    break;
                case 1:
                    nv++;
                    j = nv + 1;
                    pictureBox1.ImageLocation = String.Format("{0}{1}", j, ".jpg");
                    //правильный ли ответ выбран
                    if (otv == right) n++;
 
                    if (this.getQw()) this.showQw();
                    else
                    {
                        //больше вопросов нет
                        radioButton1.Visible = false;
                        radioButton2.Visible = false;
                        radioButton3.Visible = false;
 
                        pictureBox1.Visible = false;
 
                        //обработка и вывод результата
                        this.showLevel();
 
                        //следующий щелчок на кнопке ОК
                        //закроет окно программы
                        mode = 2;
                    }
                    break;
                case 2:     //завершение работы программы
                    this.Close();   //закрыть окно
                    break;
            }
        }
        //выводит оценку
        private void showLevel()
        {
            //ищем узел <levels>
            do
                xmlReader.Read();
            while
            (xmlReader.Name != "levels");
 
            //входим внуть узла
            xmlReader.Read();
            while (xmlReader.Name != "levels")
            {
                xmlReader.Read();
 
                if (xmlReader.Name == "level")
                    //n - кол-во правильных ответов,
                    //проверяем, попадаем ли в категорию
                    if (n >= System.Convert.ToInt32(
                        xmlReader.GetAttribute("score")))
                        break;
 
            }
 
            //выводим оценку
            label1.Text =
                "Тестирования завершенно.n" +
                "Всего вопросов: " + nv.ToString() + ". " +
                "Правильных ответов: " + n.ToString() + ".n" +
                xmlReader.GetAttribute("text");
        }
 
        private void Form1_Load_1(object sender, EventArgs e)
        {
 
        }
 
        private void pictureBox1_Click(object sender, EventArgs e)
        {
 
        }
 
        private void radioButton1_Click(object sender, EventArgs e)
        {
            if ((RadioButton)sender == radioButton1) otv = 1;
            if ((RadioButton)sender == radioButton2) otv = 2;
            if ((RadioButton)sender == radioButton3) otv = 3;
 
            button1.Enabled = true;
        }
 
        private void radioButton2_Click(object sender, EventArgs e)
        {
            if ((RadioButton)sender == radioButton1) otv = 1;
            if ((RadioButton)sender == radioButton2) otv = 2;
            if ((RadioButton)sender == radioButton3) otv = 3;
 
            button1.Enabled = true;
 
        }
 
        private void radioButton3_Click(object sender, EventArgs e)
        {
            if ((RadioButton)sender == radioButton1) otv = 1;
            if ((RadioButton)sender == radioButton2) otv = 2;
            if ((RadioButton)sender == radioButton3) otv = 3;
 
            button1.Enabled = true;
        }
    }
}

собственно далее пытался запихнуть всё в Visual studio, по какой то не понятной мне причине, не создаётся изначальная форма(
Подскажите что не так..



0



13 / 0 / 0

Регистрация: 03.11.2010

Сообщений: 125

03.06.2013, 16:29

8

А есть конечная версия? И сам файл XML можно посмотреть? в общем,выложите все что у вас есть по этому вопросу? буду очень признателен!!!



0



0 / 0 / 0

Регистрация: 10.09.2014

Сообщений: 1

24.10.2014, 06:40

9

Это очень просто. Я это сделал на Dephi-7.



0



ORLENOK

24.10.2014, 10:34


    Как написать программу для тестирования знаний

Не по теме:

Это какая то традиция, отвечать в теме раз в год?))



0



Время на прочтение
7 мин

Количество просмотров 77K

Дайте-ка угадаю: вы согласны с тем, что писать тесты — это хорошо. Это повышает надежность системы, ускоряет разработку, проект с хорошим тестовым покрытием поддерживать легко и приятно, а TDD — это вообще почти идеал процесса разработки. Но не у вас в проекте. То есть, оно клёво, но, к сожалению, сейчас столько работы — просто завал. Куча задач, одних только критических багов — два десятка, плюс надо срочно дописать этот модуль и еще написать письмо заказчику… Так что тесты, наверное, будем прикручивать уже в конце, если время останется. Или в следующем проекте. Нет, ну там точно полегче будет. Скорее всего.

Как, узнали ситуацию?

Так вот — чушь всё это. Сфера ИТ — бесконечна, как вселенная, куча работы будет всегда. Можно или начать писать тесты прямо сейчас, или не сделать этого никогда. Я тут набросал короткий план, как начать это делать за 10 шагов, по шагу в день, по 10 минут на шаг. И когда я говорю «10 минут» я имею в виду не «3 с половиной часа» и не «ну сколько-то времени, лучше побольше», а именно 600 секунд. Если у вас нету в день 600 секунд свободного времени — срочно меняйте проект, работу, профессию, страну проживания (нужное подчеркнуть), потому что это не жизнь, а каторга какая-то. Поехали.

1. Выбираем фреймворк для тестов

Не вздумайте начинать писать собственный фреймворк с нуля — оно вам надо? Тратить неделю на выбор оптимального фреймворка (да, я видел такую оценку времени на это в планах) — тоже глупо. Вот вам рецепт: набирайте в Гугле best test framework for %language% site:stackoverflow.com. Открываете первые 5 ссылок. Закрываете те из них, где рейтинг вопроса или первого ответа около нуля. Из оставшихся вкладок можно смело брать любой рекомендованный фреймворк из первой тройки с максимальным рейтингом. С вероятностью в 99.5% он вам подойдет. Поскольку на данный шаг вы пока потратили минуты 3, то оставшиеся 7 можно потратить на то, чтобы перейти на сайт фреймворка и посмотреть примеры его использования. Скорее всего, там всё будет просто и понятно (иначе он не был бы в топе рекомендаций). Но если вдруг нет — выберите другой по тому же алгоритму.

2. Пишем Hello world!

Написать Hello, world! нам раз плюнуть. Вот, например, на С++.

Hello world!

#include <iostream>

using namespace std;

int main()
{
	cout << "Hello world!" << endl;
	return 0;
}

А теперь сделаем две вещи.
Во-первых, вынесем генерацию выводимого текста в отдельные функции. Да, в две. Это для того, чтобы потом их можно было тестировать.

Hello world! после рефакторинга

#include <iostream>
#include <string>

using namespace std;

string GetHello()
{
	return "Hello";
}

string GetAdressat(string adressat)
{
	return adressat;
}

int main()
{
	cout << GetHello() + " " + GetAdressat("world") + "!" << endl;
	return 0;
}

Во-вторых, вынесем написанные функции куда-нибудь из данного файла. В зависимости от подхода и применяемого языка это могут быть просто отдельные файлы кода или библиотека. Это нужно для того, чтобы потом эти функции вызывать из тестов.
У нас будет так:

HelloFunctions.h

#include <string>
using namespace std;

string GetHello();
string GetAdressat(string adressat);

HelloFunctions.cpp

#include "HelloFunctions.h"

string GetHello()
{
	return "Hello";
}

string GetAdressat(string adressat)
{
	return adressat;
}

HelloWorld.cpp

#include <iostream>
#include "HelloFunctions.h"

using namespace std;

int main()
{
	cout << GetHello() + " " + GetAdressat("world") + "!" << endl;
	return 0;
}

3. Подключаем фреймворк к Hello world!

О подключении фреймворка к проекту наверняка очень хорошо написано на сайте фреймворка. Или на stackoverflow. Или на Хабре. Вот я, к примеру, когда-то описывал подключение Google Test. Обычно всё сводится к созданию нового проекта консольного исполняемого приложения (в скриптовых языках — отдельного скрипта), подключению к нему фрейворка парой include (importusing), подключению к проекту тестируемого кода (включением самих файлов с кодом или подключением библиотеки) — ну и всё. Если вы не верите, что этот шаг можно сделать за 10 минут — откройте Youtube, напишите в поиск название своего фреймворка и пронаблюдайте 20 видеороликов примерно одинакового содержимого, которые это доказывают.

4. Разбираемся с возможностями фреймворка

Для начала нам нужно выяснить:

  • Как написать один юнит-тест
  • Как запустить юнит-тесты

На эти вопросы обычно отвечают все те же самые статьи, о которых я говорил выше. Не лезьте сразу в дебри фреймворка. Начните с простых тестов, которые проверяют простые вещи. Тут ведь как в спорте — не надо сразу рвать большой вес, нужно сначала поставить правильную технику.

Вот, к примеру, пару тестов для нашего Hello world! на упомянутом выше Google Test:

#include "HelloFunctions.h"
#include "gtest/gtest.h"

class CHelloTest : public ::testing::Test {
};

TEST_F(CHelloTest, CheckGetHello) 
{
    ASSERT_TRUE(GetHello() == "Hello");
}

TEST_F(CHelloTest, GetAdressat) 
{
    ASSERT_TRUE(GetAdressat("world") == "world");
	ASSERT_FALSE(GetAdressat("not world") == "world");
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
5. Подключаем фреймворк к настоящему проекту

Мы уже умеем подключать фреймворк к проекту. Помните, делали на шаге №3? Всё получилось. Теперь давайте сделаем это для боевого проекта. Положите все необходимые файлы фреймворка себе под SVNGitTFSчего-у-вас-там. Сделайте тестовый проект. Подключите к нему фреймворк. Включите сборку тестового проект в процесс сборки вашего продукта. Проверьте сборку в дебаг и релиз-конфигурациях. Комитните тестовый проект, запустите сборку на билд-сервере. Всё должно быть ок. Не нагружайте пока ваших коллег появлением тестового проекта — во-первых, вы ничего не сломали, во-вторых, хвастаться вам тоже пока нечем.

6. Тестируем что-нибудь простое

Вы помните, каким образом мы выше вынесли из Hello world! часть функционала во внешний код? Обратите внимание, какими получились эти функции: они не зависят ни от глобальных переменных, ни от состояния каких-то объектов, ни от внешних данных из файлов или баз данных. Резальтат зависит только от переданных аргументов. Найдите в своём проекте что-то аналогичное. Наверняка ведь у вас есть какие-нибудь функции конвертации чего-то куда-то, сериализациидесериализации, упаковкираспаковки, шифрованиядешифрования и т.д. Не думайте пока о том, насколько нужный и полезный функционал вы тестируете. Ваша задача — написать простой тест, но для боевого проекта. Запустить, увидеть «1 тест успешно пройден».

Кстати, именно на этом этапе очень часто к скептикам приходит озарения. Вдруг оказывается, что самый простой тест, на самую элементарную функциональность — вдруг провалился. Лезем в код — и вдруг находим что-то типа

return 12; // TODO: implement later 

И оказывается, что основной код просто пока вызывал эту функцию с такими аргументами, что всё было ок, но в любой момент это могло измениться.

7. Тестируем что-нибудь посложнее

Вы уже умеете тестировать простые вещи. Теперь разберитесь как тестировать что-то, имеющее внешние зависимости. Посмотрите, как ваш фреймворк предлагает делать подготовку к запуску теста и очистку после него. Разберитесь, что такое моки и стабы. Подумайте как протестировать какой-нибудь ваш код, читающий данные из файла или из базы. Легко ли подменить источник входных данных? Может быть стоит слегка изменить код, чтобы это стало легче? Сделайте это, если нужно. Напишите для этого кода тест.

8. Пишем тест на баг

Как обычно выглядит ваша работа над багом? Вы берёте его из багтрекера, пробуете воспроизвести, если не получается — возвращаете тестеру, если получается, занимаетесь отладкой для понимания его местоположения, находите кусок кода с ошибкой, исправляете, тестируете, отдаёте тестеру. Отлично. А теперь попробуйте при работе над следующим багом между шагами «находите ошибку» и «исправляете» добавить ещё один шаг — написать тест на эту ошибку. Такой, чтобы он падал для текущего кода. Это огромное кайф, исправить код — и не лезть тестировать его руками, а запустить падавший пару минут назад тест и увидеть «успешно» на его выходе. Кроме этого эстетического удовольствия, этот тест можно отдать тестеру и использовать в дальнейшем для регрессионного тестирования (а ещё — для тестирования побочных веток продукта, проекта «в поле», и т.д.). Конечно, не всё и не всегда можно так протестировать, бывает тяжело с UI, с кроссбраузерностью, с многопоточностью. Не заморачивайтесь в случае, если написание теста займёт у вас много-много часов. В конце-концов, эта технология ведь призвана облегчить вашу жизнь, а не заставить плясать под свою дудку.

9. Первый раз TDD

Как обычно выглядит ваша работа при разработке нового функционала? Наверное, вы сначала думаете. Потом проектируете то, что будете делать — набрасываете названия интерфейсов, классов, потом названия методов, наполняете их реализацией, запускаете, отлаживаете. Отлично, менять почти ничего не надо. Просто в тот момент, когда у вас уже есть интерфейсы, классы и названия методов, но еще нет их реализации — напишите для них тесты. Простенькие — вызвали метод — проверили результат. Обратите внимание, как уже на этом этапе вы заметите нелогичность некоторых имён, недостаток или излишество аргументов в методах, ненужные или отсутствующие зависимости и т.д.. При этом сейчас пока что это исправить — почти ничего не стоит (ведь реализация ещё не написана). Подправили архитектуру, дописали тесты, запустили — увидели кучу проваленных тестов. Отлично, так и должно быть. Написали реализацию, запустили тесты — увидели большинство из них пройденными, исправили ошибки, добились успешного прохождения всех тестов — отлично, дело сделано. Вы чувствуете, как хорошо стало, какое моральное удовлетворение вы получили? Оно слегка напоминает удовольствие от получения какой-то ачивки в игре. А почему? А потому, что его можно измерить! «Код проходит 18 тестов при тестовом покрытии в 90%» — это звучит круче, намного круче чем «ну, фича вроде бы реализована, я так потыкал немножко, кажется, не падает». Это даёт право гордится. Идешь домой — и чётко понимаешь, что-то за день сделал полезное, это «что-то» измеримо, ощутимо, реально.

10. Прикручиваем запуск тестов к CI-серверу

В тестах мало смысла, если их не запускать. Запускать их вручную — долго и бессмысленно. Наверняка у вас есть билд-сервер с каким-нибудь TeamCity или CruiseControl, где собирается ваш продукт. Так вот, большинство хороших билд-серверов сразу, из коробки, поддерживают запуск тестов и даже парсят их логи и рисуют красивые отчёты. Соответствие тут, конечно, не «все совместимы со всеми», но если вы взяли тестовый фреймворк по совету в начале статьи — шансы на то, что всё заработает очень высоки. К примеру, упомянутые мною TeamCity и Google Test прекрасно дружат между собой.

Послесловие

Дотошный читатель может заметить, что пункты начиная где-то с седьмого-восьмого скорее всего не впишутся в заявленные в заголовке «10 минут на шаг». Что тут можно сказать? Считайте, что я, нехороший человек, вас слегка наколол. Однако, если вы на практике с праведным негодованием прошли эти пункты, то:

  1. У вас уже есть проект, к которому прикручены тесты. Они запускаются, работают, их больше нуля и они уже приносят вам пользу.
  2. Вы получили опыт во всём этом деле.
  3. Во второй раз у вас получится серьёзно быстрее.

Вот и решайте, стоило оно того или нет.

Где-то пункта после 8-го — хорошее время чтобы представить тестовый проект вашей команде. Объясните в 2-3 абзаца что и как, покажите простенький пример теста, заметьте, что, мол, «feel free to add your own tests», но особо не напирайте пока. Если у вас писать тесты было не принято, скорее всего первым впечатлением будет осторожный скепсис и непонимание. Это быстро лечится после второго-третьего упоминания на совещании о том, что, мол «а этот баг мы нашли благодаря тесту» или «а вот тут написан тест и мы сразу узнаем, если оно сломается снова». Программисты — народ рациональный, они поймут и подтянутся.

В современном мире эффективным способом проверки знаний считается тестирование. Тесты применяются практически во всех сферах: аттестация, образование, сертификация, психология, подбор персонала и т.д. Тестирование позволяет за короткий срок проверить знания человека и оценить его. Чтобы автоматизировать тестирование, разработчики создают специальное программное обеспечение.

Подготовительная работа

Для написания прототипа простого приложения для тестирования на языке программирования С++ мы создадим два текстовых файла.

В файл под именем test.txt запишем вопросы к тесту. Каждый вопрос в файле находится на двух строчках и состоит из вопроса и вариантов ответа.

При сохранении файла, выбираем пункт меню — Cохранить как, и устанавливаем кодировку символов ANSI для корректного отображения текста в консоли.

Во втором файле, назовём его answer.txt, в каждой строчке пропишем ответ на вопрос файла test.txt, выполняя заранее установленную последовательность.

При сохранении файла, как и ранее, выбираем пункт меню — Cохранить как, и устанавливаем кодировку символов ANSI, для корректного отображения текста в консоли.

Начинаем проектировать

В коде программы используем заголовочные файлы: iostream (обеспечивает ввод — вывод в консоль), fstream (предоставляет интерфейс для чтения или записи данных в файл), string (организовывает работу со строками). Команда using namespace std сообщает компилятору, что мы хотим использовать всё, что находится в пространстве имен std.

Функция void test()

Функция void test() читает из файла test.txt вопросы к тесту и выводит их в консоль. Открывает новый файл myanswer.txt и записывает в него ответы пользователя. По окончанию тестирования закрывает оба файла.

ifstream f — объекты класса ifstream предоставляют возможность для чтения файлов.

f.open("test.txt") — с помощью данного объекта, используя метод open, открываем файл test.txt.

ofstream out —  объекты класса оfstream позволяют нам открывать файлы для записи данных.

out.open("myanswer.txt") — для открытия файла myanswer.txt используется метод open.

Для работы с прочитанными данными из файла test.txt, используем переменную строкового типа str, ответы пользователя будем сохранять в переменную строкового типа otv.

Каждый вопрос теста нумеруем целочисленной переменной z.

Перед началом работы с данными файлов проверяем, что все рабочие файлы открылись корректно — if (f && out) —, в ином случае выводим сообщение об ошибке и покидаем тело функции:

cout << «Ошибка открытия файла !!!»;
return;

При каждой итерации цикла while, с помощью функции getline, читаем построчно данные с файла test.txt. Цикл while будет работать, пока не будут прочитаны все строки файла test.txt.

При каждой итерации цикла while в консоль выводится номер вопроса и запрос на ввод ответа.

После ввода ответа увеличиваем значение переменной z на единицу и очищаем консоль функцией system("cls").

Записываем ответ объектом out < по аналогии вывода данных в консоль инструкцией cout.

По окончании работы цикла while закрываем текстовые файлы f.close(); out.close();

Функция void result()

Функция result() открывает файлы answer.txt и myanswer.txt, сравнивает ответы пользователя с правильными ответами в файле answer.txt и выводит результат на экран.

В коде функции создаём целочисленные переменные для подсчёта правильных ответов — переменная p и ошибочная переменная n.

Для работы с правильными ответами и ответами пользователя используем строковые переменные str и otv.

С помощью классов ifstream f1(«answer.txt»), ifstream f2(«myanswer.txt») открываем файлы для чтения.

if (f1.is_open() && f2.is_open()) — проверяем, что все файлы открылись без ошибок, в ином случае покидаем функцию и сообщаем об ошибке

cout << «Ошибка открытия файла !!!»;
return;

В параметрах цикла while, используя функцию getline, читаем правильные ответы и ответы пользователя в строковых переменных str и otv.

В конструкции if (str == otv) сравниваем ответы и, если они совпадают, выводим ответ с указанием верного в консоль, а также увеличиваем значение переменной p на единицу, если это не так. Сообщаем, что ответ ошибочный и увеличиваем значение переменной n на единицу.

По окончании работы цикла while не забываем закрыть файлы f1.close(); f2.close();.

В конце работы выводим количество правильных и ошибочных ответов и выходим из тела функции.

Функция int main()

В функции main() с помощью функции system("chcp 1251>nul") устанавливаем используемый шрифт — кириллица.

Функция system(«color 1f») устанавливает цвет фона синий, а цвет букв — ярко белый.

Запускаем выполнение функций test() и result(). Устанавливаем паузу в консоли system("pause"), чтобы она не закрывалась, пока не будет нажата любая клавиша. Готово! Скачать код программы можно здесь.

Продолжаем погружаться в работу тестировщика, он же — QA, quality assurance engineer. Его задача — проверить код на наличие ошибок и работу программы в разных условиях. 

Мы уже писали о том, что ещё делают тестировщики и какие инструменты для этого используют:

  • Кто такой инженер по тестированию и стоит ли на него учиться
  • Зарплата 113 тысяч за то, чтобы ломать программы
  • Тестируем и исправляем калькулятор на JavaScript
  • Словарь тестировщика: автотесты, юнит-тесты и другие важные слова
  • Какой софт нужен, чтобы стать тестировщиком

Сегодня мы попробуем написать автотесты — чаще всего именно этим занимаются тестировщики на работе.

Что такое автотесты

Автотесты — это когда одна программа проверяет работу другой программы. Работает это примерно так:

  1. У нас есть код программы с нужными функциями.
  2. Мы пишем новую программу, которая вызывает наши функции и смотрит на результат.
  3. Если результат совпадает с тем, что должно быть, — тест считается пройденным.
  4. Если результат не совпадает — тест не пройден и нужно разбираться.

Чтобы всё было наглядно, покажем работу автотестов на реальном коде.

Исходная программа

Допустим, мы пишем интерактивную текстовую игру — в ней всё оформляется текстом, и развитие игры зависит от ответов пользователя. Мы сделали отдельный модуль, который делает четыре вещи:

  • получает имя игрока;
  • принудительно делает в имени большую букву (вдруг кто-то случайно ввёл  с маленькой);
  • добавляет к нему приветствие;
  • сформированную строку отправляет как результат работы функции.
# Собираем приветствие
def hello(name):
    # делаем первую букву имени большой
    out = name.title()
    # формируем приветствие
    out = 'Привет, ' + out + '.'
    # возвращаем его как результат работы функции
    return out

Эта функция хранится в файле hello_function.py — так мы разбиваем программу на модули, каждый из которых делает что-то своё. 

Напишем начало основной программы, которая запрашивает имя, формирует приветствие и добавляет к нему стартовую фразу:

# импортируем функцию из другого файла
from hello_function import hello
# объясняем, что нужно сделать пользователю
print("Введите имя, чтобы начать игру")

# спрашиваем имя
name = input("Как вас зовут: ")
# обрабатываем имя и формируем приветствие
result = hello(name)
# добавляем вторую строку
print(result + " nДобро пожаловать в «Код»!")

Сохраним это в новом файле start.py и запустим его:

Делаем простые автотесты на Python

Вроде работает, но хорошо бы проверить, а всегда ли приветствие будет формироваться правильно? Можно сделать вручную, а можно написать автотест.

Пишем автотест

Первое, что нам нужно сделать, — подключить стандартный модуль для автотестов unittest. Есть модули покруче, но для наших проектов стандартного хватит с запасом. Также получаем доступ к функции hello() из файла hello_function.py — работу именно этой функции мы будем проверять автотестом.

# подключаем модуль для автотестов
import unittest
# импортируем функцию из другого файла
from hello_function import hello

А теперь самое важное: нам нужно объявить класс и функцию, внутри которой и будет находиться наш тест. Причём название функции должно начинаться с test_, чтобы она выполнялась автоматически.

Внутри функции делаем такое:

  • формируем данные, которые мы отправляем в тестируемую функцию;
  • прописываем ожидаемый результат.

Этими действиями мы как будто вызываем ту функцию и смотрим, получилось ли то, что нам нужно, или нет. При этом нам не нужно обрабатывать результаты тестов — за нас это сделает модуль unittest. 

Для запуска тестов добавляем в конец кода стандартный вызов. Читайте комментарии, чтобы лучше вникнуть в код:

# подключаем модуль для автотестов
import unittest
# импортируем функцию из другого файла
from hello_function import hello

# объявляем класс с тестом
class HelloTestCase(unittest.TestCase):
    # функция, которая проверит, как формируется приветствие
   def test_hello(self):
        # отправляем тестовую строку в функцию
        result = hello("миша")
        # задаём ожидаемый результат
        self.assertEqual(result, "Привет, Миша.")

# запускаем тестирование
if __name__ == '__main__':
    unittest.main() 

После запуска мы увидим такое. Ответ «OK» означает, что наш тест сработал и завершился без ошибок:

Делаем простые автотесты на Python

Тест пройден за ноль секунд

Ещё такие тесты позволяют найти ошибки в самом коде. Допустим, разработчик забыл добавить принудительный перевод большой буквы в имени, и тогда тест не пройдёт. Если получится, система даже подсветит, что именно не совпало в результате, — в нашем случае это первая буква имени.

Делаем простые автотесты на Python

Тест не пройден, а автотестер даже указал в чём

Что дальше

Мы написали самый простой тест и всего с одним условием. При этом мы не проверили тестами работу основной программы — в реальном проекте это тоже нужно было бы сделать. Чтобы попрактиковаться, мы сделаем тесты для одного из наших старых проектов на Python. Заодно проверим, нет ли там каких ошибок, которые мы не заметили.

Вёрстка:

Кирилл Климентьев

МУНИЦИПАЛЬНОЕ ОБЩЕОБРАЗОВАТЕЛЬНОЕ
УЧРЕЖДЕНИЕ СРЕДНЯЯ ОБЩЕОБРАЗОВАТЕЛЬНАЯ ШКОЛА

«ПЕРСПЕКТИВА»

ГОРОДСКОГО ОКРУГА  ВЛАСИХА МОСКОВСКОЙ
ОБЛАСТИ

143010, МОСКОВСКАЯ ОБЛАСТЬ, ПОСЕЛОК
ВЛАСИХА,

МКР. ШКОЛЬНЫЙ, Д.10,

PERSPECTIVASCHOOL@YANDEX.RU

Проектная работа на тему:

«Создание программы для
тестирования обучающихся»

Выполнила ученица 10 «Б»

Стариченко Ольга

Руководитель
проекта

учитель информатики и ИКТ

Зеленченко Иван
Алексеевич

2022г.

Оглавление

Введение

Глава
1

1.1.
Компьютерное тестирование

1.2.
Delphi
7

Глава
2 Код программы

Глава
3 Форма эксель

Заключение

Список
литературы

Введение

В 21 веке учителям
требуется оптимизировать свою работу. Одним из направлений совершенствования
процесса обучения является разработка оперативной системы контроля знаний,
умений и навыков, позволяющей объективно оценивать знания обучающихся, выявляя
имеющиеся пробелы и определяя способы их ликвидации. Для этого используются
различные цифровые среды. Большинство из них работают только в определенных
условиях и характеристиках компьютера. Рассмотрев все существующие на данный
момент среды, я решила разработать универсальное программное обеспечение,
которое может работать на любом компьютере с ОС windows. Единственным условием
является наличие программного обеспечения
MicrosoftExcel 2007 и новее. Данная среда позволяет один раз запрограммировать
тест, который потом можно использоваться множество раз без необходимости
создавать его заново. Для практической работы выбран язык программирования
Delphi 7, так как это в настоящее время наиболее простой сервис, имеющий все
необходимые функции.

Цель
проекта
— Создание электронного
теста, с помощью языка программирования
Delphi 7, для промежуточной аттестации уровня знаний обучающихся
нашей школы.

Задачи проекта

– Изучить литературу по данной
тематике;

– Ознакомиться с интерфейсом
программы «Delphi 7»;

– Внести соответствующие вопросы в
программу;

– Выставить параметры оценивания заданий;

– Апробировать созданный тест;

– Устранить выявленные недоработки

Актуальность
проекта
— Актуальность проекта
обусловлена тем, что растёт интерес к тестированию в качестве метода оценки
качества образования.Каждый преподаватель стараясь усовершенствовать методы
опроса своих учеников, приходит к мысли об электронном тестировании. В целях
экономии времени преподавателя можно пользоваться данной платформой, которая
автоматически будет выставлять баллы за тестирование. Старые методы
тестирования уже не настолько эффективны в оценивании. Ведь компьютерный тест
может выдавать вопросы не по порядку, разграничивать степень сложности, а также
отсылать результат прохождения прямо на компьютер преподавателя.

Продукты проекта
— Приложение для проверки знаний учащихся

Глава 1

1.1. Компьютерное тестирование

Тесты давно стали неотъемлемой частью
рабочих будней любого педагога. Раньше приходилось печатать их на бумаге,
собирать листочки или тетради у каждого ученика, вручную проверять и
анализировать результаты. Сейчас в нашем распоряжении существуют
онлайн-сервисы, которые серьезно экономят время и ресурсы. Мы получаем новые
возможности: дистанционный сбор ответов, автоматическую оценку результатов,
мгновенное редактирование материалов.

Компьютерное
тестирование
– разновидность
тестирования с использованием современных технических средств, имеющее ряд
преимуществ по сравнению с традиционным бланочным тестированием

(получение мгновенного результата, исключение предвзятости, нормирование
трудности и объёма тестовых заданий, массовость, лёгкость обработки
результатов, возможность тестирующих программ работать в режиме обучения).

Компьютерное тестирование
используется, как правило, лишь как средство объективного контроля знаний после
завершения изучения каждого раздела (модуля) учебной программы по дисциплине.
Контролирование, оценивание уровня знаний обучающихся с одной стороны это
индикатор качества обучения – определение успеваемости обучающегося, а с другой
стороны – показатель совершенства эффективности дидактической системы (методики
обучения и организации учебного процесса).

Компьютерное
тестирование имеет ряд преимуществ:

• Моментальное  получение
отметки каждым обучающимся после выполнения теста;

• Обучающиеся самостоятельно
могут оценить свои знания, возможности;

• Одновременную
проверку знаний всех обучающихся;

• Формировать у
обучающихся мотивацию для подготовки к каждому занятию, дисциплинирует их,
развивает у обучающихся добросовестность и аккуратность;

• Проверить большой
объем изученного материала;

• Избежать затрат
на бумагу.

Недостатки тестовых
форм контроля:

• Данные,
получаемые преподавателем в результате тестирования, хотя и включают в себя
информацию о пробелах в знаниях по конкретным разделам, но не всегда позволяют
судить о причинах этих пробелов;

• Обучающийся при
тестировании, в отличие от устного или письменного экзамена, не имеет
достаточно времени для глубокого анализа темы;

• В тестировании
присутствует элемент случайности. Например, обучающийся, не ответивший на
простой вопрос, может дать правильный ответ на более сложный.

• Изначальные
затраты времени на изготовление пакета тестов по дисциплине очень большие;

• Обеспечение объективности и
справедливости теста требует принятия специальных мер по обеспечению
конфиденциальности тестовых заданий. При повторном применении теста желательно
внесение в задания изменений.

Для создания тестов по предметной
области разрабатываются специальные инструментальные программы-оболочки,
позволяющие создавать компьютерные тесты путем формирования базы данных из
набора тестовых заданий.

1.2. Delphi 7

Мечта программистов о среде
программирования, в которой бы простота и удобство сочетались с мощью и
гибкостью, стала реальностью с появлением среды
Delphi. Она обеспечивала визуальное проектирование пользовательского
интерфейса, имела развитый объектно-ориентированный язык
ObjectPascal (позже переименованный в Delphi) и уникальные по своей простоте
и мощи средства доступа к базам данных. Язык
Delphi по возможностям значительно превзошел язык Basic и даже в чем-то язык C++, но при этом он оказался
весьма надежным и легким в изучении. В результате, среда
Delphi позволила программистам легко
создавать собственные компоненты и строить из них профессиональные программы.
Среда оказалась настолько удачной, что по запросам любителей
C++ была позже создана среда C++Builder — клон среды Delphi на основе языка C++ (с расширенным синтаксисом).Среда Delphi стала, по сути, лучшим средством программирования для операционной
системы
Windows.

У языка Delphi есть
одно очень важное преимущество перед остальными коммерчески успешными языками —
он великолепно подходит для обучения программированию. Поэтому многие рекомендуют
его в качестве первого языка для всех учеников и студентов, собирающихся стать
профессиональными программистами. Единственная проблема в освоении среды Delphi
— это ее гигантский объем. Новичок просто теряется в этом море поистине
безграничных возможностей.

Подпрограммы:

В практике программирования часто
встречается ситуация, когда одну и ту же группу операторов требуется выполнить
без изменений в нескольких местах программы. Чтобы избавить программиста от
многократного дублирования одинаковых фрагментов, была предложена концепция
подпрограмм.

Подпрограммой
называется именованная логически законченная группа операторов, которую можно
вызвать по имени (т.е. выполнить) любое количество раз из различных мест
программы. В языке Delphi подпрограммы оформляются в виде процедур и функций.

Процедура
— это подпрограмма, имя которой не может использоваться в выражениях в качестве
операнда. Процедура состоит из заголовка и тела. По структуре ее можно
рассматривать как программу в миниатюре. Когда процедура описана, ее можно
вызвать по имени из любой точки программы. Когда процедура выполнит свою
задачу, программа продолжится с оператора, следующего непосредственно за
оператором вызова процедуры. Использование имени процедуры в программе
называется оператором вызова процедуры.

Функция
также является подпрограммой, но в отличие от процедуры ее имя может использоваться
в выражениях в качестве операнда, на место которого подставляется результат
работы этой функции.

Все процедуры и функции языка Delphi
подразделяются на две группы: встроенные и определенные программистом.
Встроенные процедуры и функции являются частью языка и могут вызываться по
имени без предварительного описания. Процедуры и функции программиста пишутся
программистом, т.е. вами, в соответствии с синтаксисом языка и представляют
собой локальные блоки. Предварительное описание процедур и функций программиста
обязательно.

Процедуры программиста:

Очевидно, что встроенных процедур (Рис.1.
Код процедуры) и

Рис.1. Код процедуры

функций
для решения большинства прикладных задач недостаточно, поэтому приходиться
придумывать собственные процедуры и функции. По своей структуре они очень
напоминают программу и состоят из заголовка и блока. Заголовок процедуры
состоит из зарезервированного слова procedure, имени процедуры и
необязательного заключенного в круглые скобки списка формальных параметров. Имя
процедуры — это идентификатор, уникальный в пределах программы. Формальные
параметры — это данные, которые вы передаете в процедуру для обработки, и
данные, которые процедура возвращает (подробно параметры описаны ниже). Если
процедура не получает данных извне и ничего не возвращает, формальные параметры
(в том числе круглые скобки) не записываются. Тело процедуры представляет собой
локальный блок, по структуре аналогичный программы:

Понятие процедуры является
чрезвычайно важным, так как именно оно лежит в основе одной из самых популярных
технологий решения задач на языке Delphi. Технология эта внешне проста: задача
разбивается на несколько логически обособленных подзадач и решение каждой из
них оформляется в виде отдельной процедуры. Любая процедура может содержать в
себе другие процедуры, их количество ограничено только объемом памяти вашего
компьютера.

Параметры процедур

Параметры
служат для передачи исходных данных в подпрограммы и для приема результатов
работы этих подпрограмм. Исходные данные передаются в подпрограмму с помощью
входных параметров (
const),
а результаты работы подпрограммы возвращаются через выходные параметры(
out).
Параметры могут быть входными и выходными одновременно(
var).

Рекурсивные подпрограммы:

В ряде приложений алгоритм решения
задачи требует вызова подпрограммы из раздела операторов той же самой
подпрограммы, т.е. подпрограмма вызывает сама себя. Такой способ вызова
называется рекурсией. Рекурсия полезна прежде всего в тех случаях, когда
основную задачу можно разделить на подзадачи, имеющие ту же структуру, что и
первоначальная задача. Подпрограммы, реализующие рекурсию, называются рекурсивными.
Для понимания сути рекурсии лучше понимать рекурсивный вызов как вызов другой
подпрограммы. Практика показывает, что в такой трактовке рекурсия
воспринимается значительно проще и быстрее. При написании рекурсивных
подпрограмм необходимо обращать особое внимание на условие завершения рекурсии,
иначе рекурсия окажется бесконечной и приложение будет прервано из-за ошибки
переполнения стека.

Процедурные типы данных

Наряду с уже известными типами данных
в языке Delphi введен так называемый процедурный тип, с помощью которого
обычные процедуры и функции можно интерпретировать как некоторую разновидность
переменных. Определение процедурного типа состоит из зарезервированного слова procedure
или function, за которым следует полное описание параметров. Для функции
дополнительно указывается тип результата. Символические имена параметров
никакой роли не играют, поскольку нигде не используются. При работе с
процедурной переменной важно понимать, что она не дублирует код подпрограммы, а
содержит лишь ее адрес.

Компонент Delphi Button— стандартная кнопка
делфи, кнопка имеет на поверхности надпись, описывающую её назначение при
нажатии. Основное событие для кнопки является OnClick, выполняемое при нажатии,
при этом кнопка меняет внешний вид, подтверждая этим происходящее действие
визуально. Сразу после отпускания кнопки, выполняется действия в обработчике
OnClick. Кнопку можно нажать не только щелчком мыши, но и комбинацией клавиш,
чтобы задать комбинацию необходимо перед символом используемым в комбинации
поставить символ амперсанта «&». После чего пользователь вместо щелчка мыши
может использовать сочетание клавиш Alt и клавишей выделенного символа.

Компонент Delphi Label предназначен
для показа текста на форме нашей программы, которые не будут меняться в течение
работы программы. Текст надписи компонента Label можно изменить, но делается
это только программно. Текст, отображаемый в компоненте, определяется значением
свойства Caption. Он прописывается в процессе проектирования или задается
программно во время выполнения программы.

Компонент DelphiImage
предназначен для отображение на форме графических изображений по умолчанию
выводит на поверхность формы изображения представленных в
bmp
формате. Для вывода изображений в
jpg
формате необходимо в дерективе
uses
подключить модуль
JPEG. После
размещения  на форме компонента
Image,
он принимает вид выделенной прямоугольной области.

Загрузить картинку можно в коде
программы, добавив строку (Рис.2. Загрузка изображения):

Image1.Picture.LoadFromFile(<имя_файла>);

Рис.2. Загрузка
изображения

Кроме этого, загрузить изображения
можно с помощью Object Inspector. Для этого находим свойство Picture и слева от
него нажимаем на три точки. Открывается окно Picture Editor и в нем выбираем
загрузить(Load), в раскрывшемся окне выбираем файл изображения.

Глава 2 Код
программы

Для программы было придумано
несколько форм:

·       
Start (Рис.3 Forma start):
отвечает за внос ФИО участника тестирования, которое вносится в поле
FIO,
тип
Edit, после нажимается кнопка
«Приступить», тип
Button,
которое выполняет следующую функцию:

(Рис.3 Forma start):

procedure TStart.Button1Click(Sender:
TObject);

begin

xl:=CreateOleObject(‘Excel.Application’);

xl.Workbooks.Open[ExtractFilePath(paramstr(0))+’/infa.xlsx’,0,false,
password:=’06061996′];

xl.Visible:=false;

xl.Range[‘F2’]:=FIO.Text;

xl.activeWorkbook.save;

nom:=xl.Range[‘A2’];

usl:=xl.Range[‘B2’];

z:=Strtoint(xl.range[‘m2’]);

Form2.nomer.Caption:=nom;

Form2.zadanie.Caption:=usl;

xl.ActiveWorkbook.Close;

start.Hide;

form2.showmodal;

end;

Согласно коду программы «xl.Range[‘F2’]:=FIO.Text» ФИО участника заносится в ячейку «F2» Excel файла infa.xlsx.  После чего программа переходит на 2 основную форму Form2.

·       
Form2 (Рис.4. Form2):
основная форма на которой присутствуют несколько полей:

o  
Tlabel: отвечающий за
отображения (загрузку) вопроса из
excel
файла,
согласно строке  «Zadanie.capion:=usl»,

Рис.4. Form 2

usly:=(‘B’+a);

xl.Range[‘C’+a]:=otvet.Text
;

otvet.Text:=»;

z:=z+1;

a:=Inttostr(z);

xl.Range[‘M2’]:=a;

nomy:=(‘A’+a);

usly:=(‘B’+a);

nom:=xl.Range[nomy];

usl:=xl.Range[usly];

nomer.Caption:=nom;

zadanie.Caption:=usl;

xl.activeWorkbook.save;

xl.ActiveWorkbook.Close;

o  
Блок otvet имеет тип Edit – вносится ответ ученика и
записывается в
excel файл, чтобы учитель мог перепроверить или выяснить «пробелы» в
знаниях ученика.

o  
2 кнопки типа Button: «Следующий» и «назад», которые
отвечают за переключения вопросов, параллельно согласно коду сохранять и
подгружает предыдущие ответы ученика:

o  
Кнопка «Закрыть» типа Button закрывает тестирование, не
завершив само тестирование, но промежуточные ответы ученика сохраняются в файл,
тем самым предотвращает потерю ответов – есть возможность восстановить варианты
ответов.

o  
Beta-тестирование присутствует
кнопка «Загрузить рисунок», которая позволяет учителю подгрузить фото/картинку
(например: графики функция, географические задание и т.д.), что позволяет
разнообразить типы заданий:

z:=Strtoint(xl.range[‘m2′]);
 копирует название

В
завершении тестирование ученику выводится сообщение с его результатом.

Глава
3 Форма эксель

Для создания теста учителям
предложена готовая форма, которую преподавателям требуется вносить свои
изменения согласно требованиям:

·       
Столбец A отвечает за то, какой номер
вопроса задается учащемуся. В последующих ячейках столбца
A идут номера вопросов.

·    
Столбец B отвечает за то, какое условие
ставится учащемуся. В последующих ячейках столбца
B перечисляются условия, т.е.
вопрос и варианты ответа. (Рис.3. Образец заполнения формы
Excel (1)).

Рис.3. Образец заполнения формы Excel (1)

·       
Столбец C прописывает, какой ответ выбрал
ученик.

·       
Столбец D прописывает правильный ответ.

·       
Столбец E прописывает количество баллов,
набранное учеником, после сравнения столбцов
C и D.

·       
В столбце F прописывается фамилия
обучающегося.

·       
Столбец G прописывает количество номеров
в тесте, заданное преподавателем.

·       
В столбце H выводится итоговая оценка, на
основании набранных баллов. (Рис.4. Образец заполнения формы
Excel (2))

Рис.4. Образец
заполнения формы
Excel (2)

Рис.5. Общий
образец заполнения формы
Excel

Заключение

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

При исследовании этой темы
я выяснила что, большинство учебных заведений пользуются доступностью программы
Delphi 7, которая достаточно популярна в наше время, тем самым преподаватели
намного упрощают проверку знаний своих обучающихся.

В программе на мой взгляд
имеется упрощённый интерфейс, что не вызовет трудностей и большинство обучающих
справятся с прохождением теста. Небольшая сложность оказалась в поиске нужной
информации для данного теста. Я самостоятельно изучала программу. Так же
ознакомилась с литературой, устранила некоторые недочёты и выявленные ошибки
при прохождении тестирования.

В результате проделанной
работы цель достигнута: создан тест в программной оболочке Delphi 7 для проведения
контроля знаний у обучающихся.

Конечным результатом моего
проекта является электронный тест, который в дальнейшем будет использоваться
для проведения итогового оценивания качества знаний у обучающихся. Цель которая
была поставлена в начале создания была успешно достигнута.

Список литературы

1.     Основы
программирования в
Delphi
7 / Автор: Н.Б.Культин

2.     Программирование
на языке Delphi Учебное пособие / Авторы: А.Н.Вальвачев, К.А.Сурков,
Д.А.Сурков, Ю.М.Четырько

3.     Информатика.
10 класс. Углубленный уровень / Авторы: К.Ю.Поляков, Е.А.Еремин

4.     НОУ
ИНТУИТ Лекция “Подпрограммы”  https://intuit.ru/studies/courses/3488/730/lecture/25789

5.     Процедуры
https://studfile.net/preview/9763175/page:16/

6.     Встроенные
процедуры и функции с вещественными аргументами
https://poisk-ru.ru/s39971t8.html

7.     Компонент
Button
https://www.h-delphi.ru/button/

Как начать писать тесты? Сколько нужно писать? На что их нужно писать, а на что — не нужно? Стоит ли всегда применять TDD? Если вас интересуют ответы на эти вопросы, то вы читаете правильную статью. В своей жизни я написал не одну тысячу тестов всех мастей для разных платформ, использовал во все поля TDD и ставил процесс тестирования в командах, проектах и даже целых компаниях. И теперь я попробую обобщить этот опыт и поделиться им.

  • TDD
  • Дополнительные ссылки

Тестирование, как и многое в программировании, стало культом карго. Вместо осознанного движения, разработчики пытаются следовать популярным методологиям, слепо верить тому, что пишут в документации, покрывать код на 100% тестами. Я был свидетелем удаления папки с тестами (в 40 тысяч строк кода) по причине того, что их стало невозможно поддерживать. Такое тестирование чаще приводит к обратному эффекту — разработка становится дороже, а процесс медленнее, и даже если наблюдается позитивный эффект, то он дается слишком дорого.

Основная цель этой статьи — дать вам целостное понимание смысла тестирования. Понимая суть, вы сможете лучше мыслить критически и понимать, к чему нужно идти. Ну и, конечно, будет немного практических советов.

Начнем, пожалуй, с самого главного вопроса: зачем нам вообще нужно тестировать?

Чтобы быть уверенными в работоспособности нашего продукта. Заметьте, что я не написал «функций», «модуля», «кода» или «проекта». В конечном итоге имеет значение только то, что конечный продукт, которым пользуются (не всегда пользователи), работает, и делает он это хорошо. Хотя прямо сейчас это может показаться капитанством, но, как вы увидите позже, ориентация на цель позволит нам принимать правильные решения.

Следующий ключевой тезис не является особенностью процесса тестирования. Задачи можно условно поделить на два типа: они либо завершены, либо нет, а завершенность задач второго типа — это шкала, где 0 — это «ничего не сделано», а 1 — это сделано на 100%. При решении таких задач 100%-решение часто оказывается недостижимым из-за сверхвысоких накладных расходов.

Приведу прекрасный пример. Для многих сервисов критично такое понятие как SLA или, проще говоря, доступность сервиса. Например, на хостинговых площадках пишут что-то в духе «мы обеспечиваем доступность 99.9% наших серверов». Давайте прикинем, сколько часов за год хостинг может оказаться недоступен в рамках его SLA: 0.001 * 365 * 24 = 8.7. В принципе, неплохо.

Читайте также:
Чем отличается обучение на Хекслете от других школ

Предположим, что обеспечение такого уровня доступности обходится компании в 1000$. А во сколько обойдется компании добавление каждой новой девятки в конце? То есть обеспечение 99.99, 99.999 и так далее. Насколько мне известно, на таком уровне обеспечения происходит экспоненциальный (взрывной) рост стоимости. Я уже не говорю про то, что 100%-доступность является фантастикой.

Этот пример ярко демонстрирует то, что в задачах с плавающим результатом главным принципом является «максимальный результат за минимальные ресурсы». Другими словами, ищется баланс, при котором мы получаем результат, удовлетворяющий стейкхолдеров (заинтересованные лица), за приемлемый бюджет/сроки.

Теперь возвращаемся к нашим тестам и обнаруживаем, что тесты относятся именно к этому типу задач. Добавление первых тестов в проект дает невероятный эффект. Покрытие в 50% (половина кода вызывается в тестах) получается почти сразу, и по сравнению с отсутствием тестов — мы на два корпуса впереди. Дальше ситуация начинает меняться, и где-то на уровне 70-90% начинается резкое замедление роста покрытия, тесты становятся все более точечными, дорогими. Возрастает сложность их поддержки, рефакторинга.

Этот процесс бесконечен. Добиться 100% покрытия очень дорого и, скорее всего, неоправданно (см. пример выше). Кроме того, никакие тесты не дают вам полную гарантию работоспособности.

Кроме количества тестов и их качества, на стоимость также влияет то, какой тип тестов мы используем. Существует множество классификаций видов тестов, таких как: «по знанию системы», «по степени автоматизации», «по времени проведения тестирования». На этом этапе нас интересует только одна классификация: «по степени изолированности компонентов»:

  • Модульное тестирование
  • Интеграционное тестирование
  • Системное тестирование (приемочное)

Именно здесь начинаются проблемы. Во-первых, идут настоящие религиозные войны на тему того, что называть модульным тестированием, а что не называть. Во-вторых, эти типы тестов подаются как нечто конкретное с большим количеством требований для того, чтобы соответствовать одной из этих категорий. Такое положение вещей приводит к тому, что программисты думают, в первую очередь, не о результате, а о том, пишут ли они юнит-тесты в соответствии с канонами, или нет.

В действительности же нет никаких четких разделений на три уровня. Даже если вы тестируете чистую функцию (модульное тестирование), она выполняется на конкретном железе, и потенциально, на другом может перестать работать как ожидалось (это тоже в каком-то смысле интеграционное тестирование).

Так вот, есть только шкала. Чем более простую и мелкую часть системы мы тестируем — тем дешевле тесты, чем более сложную (составную) — тем дороже. И ваша задача как специалиста — исходить не из того, чтобы соответствовать своим представлениям о видах тестирования, а писать тесты так, чтобы они в идеале покрывали большее число кейсов при небольших затратах. Я уверен, что на этой фразе некоторые разработчики напряглись, потому что в их картине мира нужно обязательно писать изолированные юнит-тесты, а приемочные должны писать только тестировщики. Не буду разводить полемику, просто скажу, что бывает по-разному. Есть проекты, в которых процент юнит-тестов (в самом жестком понимании) составляет доли процента от всех остальных тестов (как в Хекслете, хе-хе), а есть те, где пишут только приемочные тесты (отдельные тестировщики).

Теперь вы готовы, и я попробую ответить на вопросы, поставленные в начале статьи. Предположим, что вы пишете программу (утилиту командной строки), которая принимает на вход файл и слово, которое нужно найти в этом файле. В результате своей работы программа печатает на экран все строчки из файла, в которых встречается это слово. Такая утилита действительно существует и называется grep. С ней знакомо большинство разработчиков.

Учитесь:
Курс по автоматическому тестированию на JS, а для опытных программистов — продвинутое.

Обычно в таких программах не всегда сразу понятно, какой будет архитектура. Многое зависит от того, что будет добавлено в процессе, например, форматы вывода, поддерживаемые форматы входа, обход директорий (рекурсивный), нечеткий поиск и многое другое.

Основной наблюдаемый мной анти-паттерн в разработке подобных библиотек — это тесты на внутренние мелкие компоненты. Те самые юнит-тесты. Почему такой подход непродуктивен? Возможно, это и не очевидно, но такое тестирование, хоть и является модульным, но не является дешевым и качественным. Но, как…?

Мы уже говорили о том, что архитектура проекта еще неизвестна, и, как правило, внутреннее разделение на файлы/модули/классы/функции, меняется с космической скоростью. В течение часа все может быть переписано несколько раз. Но теперь вместе с кодом нужно постоянно править тесты, что начинает раздражать. Программист начинает сомневаться в том, что они вообще ему нужны, и нередко просто перестает их писать. Другие продолжают мучаться и переписывать их, хотя чаще происходит другое. Написанные тесты начинают вас сковывать и мозг шлет команды «ты потратил время, оставь все как есть». Постепенно рефакторить становится все сложнее и ленивее. Это очень похоже на ситуацию, когда предприниматель инвестировал деньги в новое направление и, даже если бизнес уже тонет, ему тяжело отказаться, ведь было потрачено столько сил и средств (в экономике это называют sunk cost fallacy, — прим. ред.).

Так как же лучше написать тест? Надеюсь, вам уже стало очевидно, что нужно найти достаточно высокую точку входа в нашу программу, которая не зависит от внутренней реализации, и при этом выполняет поставленную задачу.

Если мы попробуем взять самый высокий уровень — прямой запуск программы в консоли, то, скорее всего, мы столкнемся с рядом проблем, такими как запуск отдельного процесса, чтение стандартных потоков и других. В случае нашей программы такое тестирование уже можно называть системным, ведь мы проверяем работу на максимально высоком уровне, вообще не касаясь внутренней реализации. Хотя такой тест и не является проблемой для опытного разработчика, в целом, стоимость подобного теста и для данной библиотеки можно назвать максимальной.

Более низкий уровень — это функция, которая принимает на вход путь до файла и подстроку для поиска, а на выходе (не печатает на экран!) отдает готовый результат, так, чтобы осталось только напечатать его. Такой вид тестов обладает самым лучшим балансом «убедиться в том, что все работает/стоимость». Они косвенно затрагивают все используемые внутренности, не зависят от реализации, очень просты в написании и крайне дешевы в поддержке. По мере стабилизации архитектуры можно добавлять тесты более низкого уровня (если становится понятно, что сложность системы слишком высока).

TDD

Описанная методика особенно хорошо работает в связке с подходом, когда тесты пишутся до кода (вместе с кодом).

Существует миф о том, что тесты нужны только для регресса, то есть для уверенности, что новый код не сломал старый. Это далеко не так. Более того, это следствие написания тестов как таковых. В некоторых ситуациях первостепенная цель написания тестов — это ускорение разработки. Да-да, вы не ослышались, написание тестов до кода/одновременно с кодом, приводит к серьезному ускорению разработки. Чаще всего такие ситуации связаны с тем, что на вход подаются сложные данные, которые как-то трансформируются и прокидываются дальше. Тестировать руками (во время разработки) такой код очень сложно, нужно подготавливать данные, нужно проверять, что результат соответствует ожидаемому.

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

Второе серьезное преимущество TDD заключается в том, что при проектировании кода мы начинаем думать не о том, как сейчас клево насоздаем файлов и разнесем по ним функции, создав десятки абстракций, и начнем думать о важных вещах. О том, как будет использоваться моя библиотека. Удивительно, но начать смотреть с такого угла (а этому учат всех стартаперов, customer development во все поля) непросто, все время хочется окунуться в прекрасный мир архитектуры.

Проектирование внешнего api — действительно важная задача, которой стоит уделить хотя бы немного времени. Именно она больше всего влияет на ту свободу действий при переработке, которую вы получите в будущем. И именно этот уровень чаще всего является той точкой, от которой стоит отталкиваться при формировании планов тестирования.

Дополнительные ссылки

  • Видео версия статьи
  • Бережливое тестирование
Когда мне понадобилось написать программу для тестирования по одному из предметов, оказалось, что в интернете мало материала на эту тему. К тому же главным недостатком найденных исходников было то, что они брали вопросы и ответы из текстового файла, что не делает надежным процесс тестирования. Поэтому я разработал свою программу.
Она состоит и четырех форм
.
Первая-для приветствия, вторая-сам процесс тестирования, третья-вывод результатов, четвертая-справка по особенностям работы(в моем случае это было пояснение некорректно отображаемых символов).

Тест состоит из 10 вопросов(их число может быть любым). Вот заготовки форм:

Form1:

Form2:

Form3:

Form4:



Дизайн

Кнопки BitBtn

За рисунок на кнопке отвечает свойство Kind. Сперва изменяете это свойство на нужное, а затем в Caption прописываете то, что будет написано на кнопке.

Формы
Размер формы выберите свой, в зависимости от длин вопросов и ответов.В BorderStyle выберите BsSingle. Так же рекомендую установить в false все свойства BorderIcons, чтобы закрытие приложения мы контролировали сами. На первой форме можно оставить в true подсвойство biMinimize. В свойстве Position выберите poDesktopCenter, чтобы форма появлялась на середине экрана.

ЛейблыСвойство AutoSize в false, чтобы кусок последней буквы не отсекался(актуально для формы с приветствием,справкой и результатами, для формы с тестированием лучше это свойство оставить в true). На форме с результатами слова «Вы набрали» и «баллов» пишутся в отдельных лейблах.
За цвет, размер и тип текста отвечает свойство Font(color, size, name). Для тестирования я использовал шрифт Verdana. Для отображения надписей на других формах-Monotype Corsiva.

MainMenuЩелкаем по нему дважды и в Caption прописываем «Справка». Для вызова обработчика события нужно щелкнуть по слову «Справка»  в окне с заголовком Form2->MainMenu1 .

Вот код для каждой из форм:

Важно!
Текст модуля нельзя копировать напрямую, т.к. это вызовет ошибки при компиляции(относится к обработчикам событий). Следует сперва щелкнуть, например, по кнопке, а затем вставить код:

Пример для

BitBtn1:

Щелкаем дважды по кнопке BitBtn1, появится:

void __fastcall TForm3::BitBtn1Click(TObject *Sender)
{

      }

Затем между фигурными скобкам вставляем код:


 Form1->Close();
 Form2->Close();
 Form3->Close();
 Form4->Close(); 

И в итоге получаем:

void __fastcall TForm3::BitBtn1Click(TObject *Sender)
{
 Form1->Close();
 Form2->Close();
 Form3->Close();
 Form4->Close();       
}


Unit1.cpp

//—————————————————————————

#include <vcl.h>
#pragma hdrstop

#include «Unit1.h»
#include «Unit2.h»
#include «Unit3.h»
#include «Unit4.h»
//—————————————————————————
#pragma package(smart_init)
#pragma resource «*.dfm»

extern int pravil_otvet;//переменная, для хранения правильного ответа к вопросу

TForm1 *Form1;
//—————————————————————————
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//—————————————————————————

void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
 Form1->Close();
 Form2->Close();
 Form3->Close();
 Form4->Close();
}
//—————————————————————————
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{

           Form2->Label5->Caption=»Как называют манекенщицу супер-класса?»;
           Form2->Label1->Caption=»Топ-модель»;
           Form2->Label2->Caption=»Тяп-модель»;
           Form2->Label3->Caption=»Поп-модель»;
           Form2->Label4->Caption=»Ляп-модель»;
           pravil_otvet=1;//присваиваем номер правильного ответа

 Form1->Visible=false;
 Form2->Visible=true;
}
//—————————————————————————

Unit2.cpp

//—————————————————————————

#include <vcl.h>
#pragma hdrstop

#include «Unit1.h»
#include «Unit2.h»
#include «Unit3.h»
#include «Unit4.h»
//—————————————————————————
#pragma package(smart_init)
#pragma resource «*.dfm»

int s=0, i=0, pravil_otvet, nomer=0;//

s-сумма правильных ответов, i-вспомогательная переменная, nomer-номер текущего вопроса

TForm2 *Form2;
//—————————————————————————
__fastcall TForm2::TForm2(TComponent* Owner)
        : TForm(Owner)
{
}
//—————————————————————————

void __fastcall TForm2::N1Click(TObject *Sender)
{
 Form4->Visible=true;       
}
//—————————————————————————
void __fastcall TForm2::BitBtn2Click(TObject *Sender)
{
 Form2->Visible=false;
 Form3->Visible=true;
 Form3->Label2->Caption=s;
}
//—————————————————————————
void __fastcall TForm2::BitBtn1Click(TObject *Sender)
{
 if(RadioButton1->Checked==true)i=1;//проверяем, какой ответ был выбран
 if(RadioButton2->Checked==true)i=2;
 if(RadioButton3->Checked==true)i=3;
 if(RadioButton4->Checked==true)i=4;
 if(i==pravil_otvet)s++;//если выбранный и правильный совпадают, то увеличиваем сумму на единичку
 i=0;//обнуление требуется для корректного подсчета суммы

  RadioButton1->Checked=false;//очищаем нажатую кнопку
 RadioButton2->Checked=false;
 RadioButton3->Checked=false;
 RadioButton4->Checked=false;

 nomer++;//номер вопроса изменяется с каждым нажатием кнопки

switch(nomer)
{
  case 1:
           Form2->Label5->Caption=»Кто вырос в джунглях среди диких зверей?»;
           Form2->Label1->Caption=»Колобок»;
           Form2->Label2->Caption=»Маугли»;
           Form2->Label3->Caption=»Бэтмен»;
           Form2->Label4->Caption=»Чарльз Дарвин»;
           pravil_otvet=2;
                   break;

  case 2:
           Form2->Label5->Caption=»Как называлась детская развлекательная программа, популярная в прошлые годы?»;
           Form2->Label1->Caption=»АБВГДейка»;
           Form2->Label2->Caption=»ЁКЛМНейка»;
           Form2->Label3->Caption=»ЁПРСТейка»;
           Form2->Label4->Caption=»ЕЖЗИКейка»;
           pravil_otvet=1;
                   break;

  case 3:
           Form2->Label5->Caption=»Как звали невесту Эдмона Дантеса, будущего графа Монте-Кристо? «;
           Form2->Label1->Caption=»Мерседес»;
           Form2->Label2->Caption=»Тойота»;
           Form2->Label3->Caption=»Хонда»;
           Form2->Label4->Caption=»Лада»;
           pravil_otvet=1;
                   break;

  case 4:
           Form2->Label5->Caption=»Какой цвет получается при смешении синего и красного?»;
           Form2->Label1->Caption=»Коричневый»;
           Form2->Label2->Caption=»Фиолетовый»;
           Form2->Label3->Caption=»Зелёный»;
           Form2->Label4->Caption=»Голубой»;
           pravil_otvet=2;
                   break;

             case 5:
           Form2->Label5->Caption=»Из какого мяса традиционно готовится начинка для чебуреков?»;
           Form2->Label1->Caption=»Баранина»;
           Form2->Label2->Caption=»Свинина»;
           Form2->Label3->Caption=»Телятина»;
           Form2->Label4->Caption=»Конина»;
           pravil_otvet=1;
                   break;

             case 6:
           Form2->Label5->Caption=»Какой народ придумал танец чардаш?»;
           Form2->Label1->Caption=»Венгры»;
           Form2->Label2->Caption=»Румыны»;
           Form2->Label3->Caption=»Чехи»;
           Form2->Label4->Caption=»Молдаване»;
           pravil_otvet=1;
                   break;

             case 7:
           Form2->Label5->Caption=»Изучение соединений какого элемента является основой органической химии?»;
           Form2->Label1->Caption=»Кислород»;
           Form2->Label2->Caption=»Углерод»;
           Form2->Label3->Caption=»Азот»;
           Form2->Label4->Caption=»Кремний»;
           pravil_otvet=2;
                   break;

  case 8:
           Form2->Label5->Caption=»Кто открыл тайну трёх карт графине из «Пиковой дамы» А. С. Пушкина?»;
           Form2->Label1->Caption=»Казанова»;
           Form2->Label2->Caption=»Калиостро»;
           Form2->Label3->Caption=»Сен-Жермен»;
           Form2->Label4->Caption=»Томас Воган»;
           pravil_otvet=3;
                   break;

  case 9:
           Form2->Label5->Caption=»В какой стране была пробурена первая промышленная нефтяная скважина?»;
           Form2->Label1->Caption=»Кувейт»;
           Form2->Label2->Caption=»Иран»;
           Form2->Label3->Caption=»Ирак»;
           Form2->Label4->Caption=»Азербайджан»;
           pravil_otvet=4;
                   break;

  case 10:
           BitBtn1->Enabled=false;
           RadioButton1->Enabled=false;//делаем кнопки «не нажимаемыми», чтобы пользователь нажал на «закончить тест»
           RadioButton2->Enabled=false;
           RadioButton3->Enabled=false;
           RadioButton4->Enabled=false;
}
}
//—————————————————————————

Unit3.cpp

//—————————————————————————

#include <vcl.h>
#pragma hdrstop

#include «Unit1.h»
#include «Unit2.h»
#include «Unit3.h»
#include «Unit4.h»
//—————————————————————————
#pragma package(smart_init)
#pragma resource «*.dfm»
TForm3 *Form3;
//—————————————————————————
__fastcall TForm3::TForm3(TComponent* Owner)
        : TForm(Owner)
{
}
//—————————————————————————

void __fastcall TForm3::BitBtn1Click(TObject *Sender)
{
 Form1->Close();
 Form2->Close();
 Form3->Close();
 Form4->Close();       
}
//—————————————————————————

Unit4.cpp

//—————————————————————————

#include <vcl.h>
#pragma hdrstop

#include «Unit1.h»
#include «Unit2.h»
#include «Unit3.h»
#include «Unit4.h»
//—————————————————————————
#pragma package(smart_init)
#pragma resource «*.dfm»
TForm4 *Form4;
//—————————————————————————
__fastcall TForm4::TForm4(TComponent* Owner)
        : TForm(Owner)
{
}
//—————————————————————————

void __fastcall TForm4::BitBtn1Click(TObject *Sender)
{
 Form4->Visible=false;//скрываем форму справки после просмотра       
}
//—————————————————————————

Программа в процессе работе:

Если вам требуется вместе с вопросом показать изображение, то используйте компонент Image и его свойство Picture. Разместите на форме нужно количество этих компонентов и в каждый подгрузите нужную картинку. Для всех свойство Visible установите в false. Затем в нужном вопросе допишите код, например:

           Form2->Label5->Caption=»Как звали невесту Эдмона Дантеса, будущего графа Монте-Кристо? «;
           Form2->Label1->Caption=»Мерседес»;
           Form2->Label2->Caption=»Тойота»;
           Form2->Label3->Caption=»Хонда»;
           Form2->Label4->Caption=»Лада»;
           Form2->Image1->Visible=true;
           pravil_otvet=1;
                   break;

Т.е. вы покажете изображение подгруженное в

Image1. Но чтобы при переходе к следующему вопросу изображение убралось или заменилось новым, перед switch нужно дописать:Form2->Image1->Visible=false;
Form2->Image2->Visible=false;

Form2->Image[i]->Visible=false;

В зависимости от количества ваших изображений. Это простой способ и поможет избежать отображения сразу двух изображений. Как вариант-дописать в следующем вопросе:

  case 3:
           Form2->Label5->Caption=»Как звали невесту Эдмона Дантеса, будущего графа Монте-Кристо? «;
           Form2->Label1->Caption=»Мерседес»;
           Form2->Label2->Caption=»Тойота»;
           Form2->Label3->Caption=»Хонда»;
           Form2->Label4->Caption=»Лада»;
           Form2->Image1->Visible=true;
           pravil_otvet=1;
                   break;

  case 4:

Form2->Image1->Visible=false; //скрываем
           Form2->Label5->Caption=»Какой цвет получается при смешении синего и красного?»;
           Form2->Label1->Caption=»Коричневый»;
           Form2->Label2->Caption=»Фиолетовый»;
           Form2->Label3->Caption=»Зелёный»;
           Form2->Label4->Caption=»Голубой»;
           Form2->Image2->Visible=true; //успешно скрыв старое изображение, показываем новое
           pravil_otvet=2;
                   break;

Понравилась статья? Поделить с друзьями:
  • Как написать программу для телефона на java
  • Как написать программу обучения персонала
  • Как написать программу для такси
  • Как написать программу наставничества
  • Как написать программу для стиральной машины