пятница, 6 августа 2010 г.

Скрипт автоматического тестирования интерфейса

По работе мне требовалось заполнить около 1000 сложных форм. Естественно делать вручную мне этого не хотелось и у меня родился скрипт для автоматического тестирования.

Программа состоит из 2 частей:
  • Запись действий: положение мыши, нажатие на кнопки, время событий
  • Воспроизведение записанных событий.
Управление клавиатурой будет добавлено поздней.

Описание классов:
#ifndef mouseH
#define mouseH

#include <vector>
#include <dos.h>
#include <time.h>
#include <windows.h>

struct step { //структура для хранения событий
        int x, y; //положение курсора
        int sleep; //время до события от предыдущего
};

class TMouseRec { //класс записи событий
        private:
                int second; //время для записи
                int teak;
                time_t time_start; //время старта
                time_t time_cur; //текущее время
                time_t time_bef; //время предыдущего события
        public:
                std::vector stp; //вектор структур событий
        public:
                TMouseRec(int _second);
                void getXY(int &x, int &y); // положение курсора
                void setStep();
                void start(); //точка входа
};

class TMousePlay { //класс воспроизведения, записанных событий
        private:
                std::vector stp;
                int width, height; //ширина, высота экрана
        public:
                TMousePlay(std::vector &_stp);
                void move(int x, int y); //переместить курсор
                void click(int x, int y); //нажать на кнопку
                void start(bool cycle = false);//точка входа
};

#endif

Реализация классов:
#include "mouse.h"

TMouseRec::TMouseRec(int _second) {
         second = _second;
}

void TMouseRec::start() {
        time_start = time(NULL);
        time_bef = time_start;
        while(time_cur < time_start + second) {//пока не закончилось время на запись
                time_cur = time(NULL);
                if(GetKeyState(MK_LBUTTON) < 0) {//отлавливаем левый клик
                        setStep(); //записываем событие
                        sleep(1);
                }
        }
}

void TMouseRec::setStep() {
        step buf;
        getXY(buf.x, buf.y);
        buf.sleep = time_cur - time_bef;
        stp.push_back(buf);

        time_bef = time_cur;
}

void TMouseRec::getXY(int &x, int &y) {
        POINT pt;
        if( GetCursorPos( &pt ) != 0) {
                x = pt.x;
                y = pt.y;
        }
}

TMousePlay::TMousePlay(std::vector &_stp) {
        stp = _stp;

        RECT resolution;
        HWND desktop = GetDesktopWindow();

        GetWindowRect(desktop, &resolution);

        width  = resolution.right;
        height = resolution.bottom;
}

void TMousePlay::move(int x, int y) {
        /*число возможных положений мыши = 65535x65535
        далее преобразуем записанные пиксели в положение мыши*/
        x = (int)((double)65535/width * x);
        y = (int)((double)65535/height * y);
         
        //перемещаем абсолютно
        mouse_event(MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE,x,y,0,0);
}

void TMousePlay::click(int x, int y) {
        //нажимаем, отпускаем
        mouse_event(MOUSEEVENTF_LEFTDOWN ,x,y,0,0);
        mouse_event(MOUSEEVENTF_LEFTUP   ,x,y,0,0);
}

void TMousePlay::start(bool cycle) {
        //воспроизводим события из вектора
        for(unsigned int i = 0; i < stp.size(); i++) {
                sleep(stp[i].sleep);
                move(stp[i].x, stp[i].y);
                click(stp[i].x, stp[i].y);
        }
        if(cycle) start(cycle); //если зациклено, то повторяем.
}

Пример использования:
TMouseRec *mr = new TMouseRec(20); //записываем 20 секунд
mr->start();
TMousePlay *mp = new TMousePlay(mr->stp); //воспроизведем, то что записали
mp->start(true); //крутить постоянно по кругу
П.с. Хотелось бы заметить, что эту программу можно применить и для автоматизации других рутинных процессов