OpenQuality.ru

Качество программного обеспечения

Качество программного обеспечения: в главных ролях

Лента  Радар  Блог  Опыт  
Разум  Видео  Заметки  Эпизоды


Perl: заглушки на подпрограммы

Добрый день.

Раздельное тестирование зависимых компонентов предполагает наличие заглушек (stubs) на каждый из них. Рассмотрим небольшой пример: текстовый файл test.txt содержит цитаты, а скрипт first.pl выводит их в случайном порядке.

Файл test.txt:

When I can't handle events, I let them handle themselves.
One of the keys to happiness is a bad memory.
Science is organized knowledge. Wisdom is organized life.
Reality is merely an illusion, albeit a very persistent one.
Variety is the soul of pleasure.

В скрипте применяется подпрограмма shuffle из пакета List::Util стандартной библиотеки.

#!/usr/bin/perl -w
use strict;
use List::Util qw(shuffle);
 
my @lines;
 
open (FH, "test.txt") or die "Can't read this file: $!";
 
while (<FH>) {
    push(@lines, $_);
}
 
close (FH);
 
@lines = shuffle(@lines);
foreach (@lines) {
    print $_;
}
pragma:/home/share/Work # perl first.pl
Variety is the soul of pleasure.
One of the keys to happiness is a bad memory.
When I can't handle events, I let them handle themselves.
Reality is merely an illusion, albeit a very persistent one.
Science is organized knowledge. Wisdom is organized life.

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

#!/usr/bin/perl -w
use strict;
 
use List::Util qw(shuffle);
 
my @lines;
 
sub fake {
    return @_;
}
 
undef &shuffle;
*shuffle = \&fake;
 
open (FH, "test.txt") or die "Can't read this file: $!";
 
while (<FH>) {
    push(@lines, $_);
}
 
close (FH);
 
@lines = shuffle(@lines);
foreach (@lines) {
    print $_;
}

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

pragma:/home/share/Work # perl second.pl
When I can't handle events, I let them handle themselves.
One of the keys to happiness is a bad memory.
Science is organized knowledge. Wisdom is organized life.
Reality is merely an illusion, albeit a very persistent one.
Variety is the soul of pleasure.

Подобные операции можно выполнить с помощью модулей, которые, по сути, служат обертками вокруг операций с таблицей символов. К примеру, модуль Test::MockModule предоставляет возможности для гибкой подмены подпрограмм и трассировки таких операций. В скрипте third.pl подменяется и затем “восстанавливается” подпрограмма shuffle.

#!/usr/bin/perl -w
use List::Util qw(shuffle);
use Test::MockModule;
use strict;
 
my @lines;
 
my $module = new Test::MockModule('List::Util');
 
$module->mock(shuffle => sub (@) { return @_ });
 
open (FH, "test.txt") or die "Can't read this file: $!";
 
while (<FH>) {
    push(@lines, $_);
}
 
close (FH);
 
print "Mocked subroutine:\n";
@lines = List::Util::shuffle(@lines);
foreach (@lines) {
    print $_;
}
 
print "\nOriginal subroutine:\n";
$module->unmock(shuffle);
 
@lines = shuffle(@lines);
foreach (@lines) {
    print $_;
}

Скрипт выдаст строки сначала в исходном, а затем в произвольном порядке.

Возможности установки заглушек на классы, методы и объекты будут рассмотрены в одной из следующих статей. Оставайтесь с нами.

Отправить в Twitter, Facebook, FriendFeed, ВКонтакте | Опубликовано 18.02.2009 в рубрике "Модульные тесты"

Комментарии (6)

  1. Автор комментария : Ivanych | March 3, 2009

    Хотелось бы понять, зачем вообще все это нужно.

    [Ответить]


  2. Автор комментария : Капитан Аляска | March 3, 2009

    Ivanych, представьте проект, в котором трудится много программистов. Каждый из них делает какую-то маленькую часть большого продукта. Если в проекте есть практика модульного тестирования, то у отдельно взятого программиста должна быть возможность протестировать свой код – вне зависимости от такого, в каком состоянии другие компоненты продукта. Допустим, программист пишет модуль A, который зависит от модулей B и C. В этом случае программист может поставить заглушки в тех местах, где его код зависит от этих модулей.
    Пример: есть продукт с GUI (графический интерфейс) и core (базовая функциональность). Если от core к GUI приходит время в диапазоне 06.00-10.00, то GUI должно выдавать “Доброе утро”. Если 10.00-19.00, то “Добрый день” и т.д. В этом случае поведение GUI можно проверить без core. В тех местах, где происходит вызов методов core, можно подставить заглушки, которые будут выдавать заранее известный результат.

    [Ответить]


  3. Автор комментария : Ivanych | March 3, 2009

    Правильно ли я понимаю, что вся соль статьи заключена в конструкции “*shuffle = \&fake;”, а смысл статьи, вкратце, формулируется так:

    “Чтобы не лезть далеко в код и и не переписывать вызовы функций на собственные, нужно выполнить эту конструкцию где-нибудь в начале файла, ДО вызова замещаемых функций?”

    [Ответить]


  4. Автор комментария : Капитан Аляска | March 3, 2009

    Ivanych, соль статьи – это сильно сказано :) Но в целом – да. Пример иллюстрирует механизм вызова одной подпрограммы вместо другой. В роли исходной подпрограммы (в данном случае, shuffle) выступает ваша “рабочая” подпрограмма (с вашей логикой, вашим алгоритмом, вашей обработкой), а в качестве подмены выступает заглушка (в данном случае, fake), в которой нет никакой логики, а есть заранее известный результат на выходе.

    Смысл статьи: функциональность интерпретатора Perl позволяет легко организовать заглушки на те или иные подпрограммы. Это удобно при модульном тестировании (unit testing). А вот как вы воспользуетесь такими возможностями, целиком зависит от вас и от тех задач, которые перед вами стоят.

    [Ответить]


  5. Pingback : OpenQuality.ru | Perl: заглушки на классы, методы и объекты | March 4, 2009

    […] также: Заглушки на подпрограммы в […]


  6. Pingback : OpenQuality.ru | Ступень Мартина, или двойники в Python | April 11, 2009

    […] реализовать средствами самого языка (как и в случае с Perl). В качестве иллюстрации возьмем файл account.py, […]



Добавить комментарий

Пожалуйста, исправьте результат: дважды два равно



КРАТКОЕ СОДЕРЖАНИЕ

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


ПУТЕВОДИТЕЛЬ

Список всех статей с краткой аннотацией и разбивкой по рубрикам. Открыть карту.

ПОДПИСКА

Доступ к самым интересным материалам по электропочте и RSS. Подробности.

ИЩЕЙКА