Предыстория: в 2010-й студии появились вмеру глючные Coded UI Tests. У Coded UI есть серьезное преимущество перед Selenium/Watin – студийные тесты эмулируют клавиатуру и мышку. Selenium и Watin ограничиваются вызовом событий в javascript.

Серьезный недостаток Coded UI Tests – родная поддержка только одного браузера – IE. Поддержку Firefox можно доустановить пакетом с длинным названием Microsoft Visual Studio 2010 Test Package for Mozilla Firefox (Power Tool) Beta. Пакет позволяет записывать действия в IE, и воспроизводить их, но уже в FF.

История: и вот однажды вам захотелось попробовать эту самую поддержку Firefox. Вы выкачали пакет, установили его, прочитали инструкцию и установили аддон 😉

Запустили студию,создали новый Test Project, добавили в него Coded UI Test. Записали простейшие действия:

  1. Открыть в браузере страницу http://pashapash.com/samples/1.html
  2. Кликнуть на ссылку Click Me.

Дальше вы сгенерировали код и запустили тест. Открылось новое окно IE, мышка дернулась к ссылке и кликнула на нее. Тест позеленел.

Вы смело переключаете браузер на Firefox:

[TestMethod]
public void
CodedUITestMethod1()

   
BrowserWindow.CurrentBrowser = "Firefox"
;
   
this.UIMap.ClickLink(); 
}

Запускаете и…

  • Если вы QA-автоматизатор – откроется окно мозиллы, адрес поменяется на тестовый, мышка кликнет по ссылке :)
  • Если у вас система младше Vista/W7/2008/R2 – все тоже заработает.
  • Но если вы разработчик – то с большой вероятностью вы увидите пустое окно мозиллы и ошибку в логе:

Microsoft.VisualStudio.TestTools.UITest.Extension.PlaybackFailureException: Unable to perform actions on Mozilla Firefox. Ensure that Visual Studio Test Helper extension for Mozilla Firefox is installed and enabled. Please see the package readme for more details.

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

Причина – небольшое раздолбайство авторов аддона со стороны студии. Пакет состоит из двух частей: аддона к Mozilla, и аддона к Visual Studio. Взаимодействие между ними построено следующим образом:

  • Студийный аддон выбирает случайный порт, и начинает его прослушивать.
  • Студийный аддон записывает выбранный порт в реестр и запускает браузер.
  • Аддон к браузеру читает порт из реестра, подключается к нему, и ждет команд.
  • Если со стороны браузера в течении пары секунд нет подключения – студийный аддон выбрасывает ошибку.

Раздолбайство проявляется в коде, прослушивающем порт:

IPHostEntry hostEntry = Dns.GetHostEntry("localhost");
IPEndPoint localEP = new IPEndPoint
(hostEntry.AddressList[0], port);
this.listenerSocket = new Socket(localEP.Address.AddressFamily, SocketType.Stream, ProtocolType
.Tcp);
this.listenerSocket.Bind(localEP);

Если у вас Vista/W7 – то у вас наверняка установлен IPv6. Cписок адресов для localhost – ::1 и 127.0.0.1. Адрес IPv6 будет первым в списке. Студийный аддон будет ожидать подключения только по протоколу IPv6.

Аддон со стороны Firefox так же подключается к localhost по первому попавшемуся адресу. У нормальных людей все работает. Но вы – разработчик, вы наверняка использовали встроенный в студию Web Dev Server. И Firefox при этом дико тормозил. Вы выгуглили решение – запретить Firefox-у использовать IPv6, установив network.dns.disableIPv6=true. Это официально рекомендованное решение и от Microsoft, и от Mozilla. И теперь Firefox и его аддоны не видят нужный адрес.

Самое простое решение – отредактировать C:WindowsSystem32driversetchosts, оставить (или добавить) только одну строку для localhost:

127.0.0.1    localhost

Удалить или закомментировать строку для IPv6:

# ::1        localhost

После этого тест отработает у вас не хуже, чем у QA :)

Пару дней назад поймал и починил баг с зацикливанием на многопоточной работе с Dictionary. По счастливой случайности услышал именно об этой особенности стандартного Dictionary пару недель назад, из доклада Алексея Недилько на devcamp :)

Сам баг подробно описан у Tess. Что не помешало прожить ему в проекте около 3-х лет. Самое забавное – баг жил в codebehind у ErrorPage.aspx и проявлялся при появлении нескольких одновременных специфических ошибок :)