Можно ли запустить тестовый код WatiN внешне для целевого кода C #? - PullRequest
2 голосов
/ 09 марта 2011

Моя цель - автоматизировать тестирование в элементе управления .NET WebBrowser.Приведенный ниже код работает просто отлично , если я помещаю свой тестовый код WatiN в тот же файл.

Код:

namespace WindowsFormsApplication1
{
    public partial class Form1 : System.Windows.Forms.Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    }

    private void Form1_Load(object sender, EventArgs e)
        {

            //I have WebBrowser control in the form
            //so the WatiN code below works
            var t = new Thread(() =>
            {
                Settings.AutoStartDialogWatcher = false;
                var ie = new IE(webBrowser1.ActiveXInstance);
                ie.GoTo("http://www.google.com");
                ie.TextField(Find.ByClass("lst")).TypeText("this is awesome!!");
                ie.Button(Find.ByName("btnG")).Click();
            });
            t.SetApartmentState(ApartmentState.STA);
            t.Start();

        }//end form load
   }//end class

}//end namespace

Но это не хорошосмешать тестовый код и целевой код.Итак, Я хотел бы вынуть часть кода теста WatiN и поместить его в отдельный файл C # в отдельном проекте. Но тогда, если я это сделаю, я потеряю ссылку на форму, конечно.

Я искал что-то под названием WndProc (http://dotnet.sys -con.com / node / 39039), но, похоже, это не совсем то, что я ищу.

Так что мой вопрос:

  1. возможно ли отделить код WatiN от целевого кода?

  2. , учитывая тот факт, что можно даже получить объект Formэто уже работает?(Я имею в виду получение ссылки на форму из другого консольного приложения C #, например?)

  3. , если так, может кто-нибудь показать мне пример кода?

Я попробовал ниже в отдельном проекте, но ничего не происходит после открытия Form1.Потому что процесс останавливается на Application.Run(myform)

var t = new Thread(() =>
            {
                Form1 myform = new Form1();
                Application.Run(myform);
                myform.textBox1.Text = "really";

                Settings.AutoStartDialogWatcher = false;
                var ie = new IE(myform.webBrowser1.ActiveXInstance);
                ie.GoTo("http://www.google.com");
                ie.TextField(Find.ByClass("lst")).TypeText("this is awesome!!");
                ie.Button(Find.ByName("btnG")).Click();
            });
            t.SetApartmentState(ApartmentState.STA);
            t.Start();

1 Ответ

2 голосов
/ 09 марта 2011

Прежде всего, вы действительно дублируете свой недавний вопрос.

Я часто использую WatiN, но для автоматизации браузера, а не для тестов, но я действительно не знаю, почему вы не можете использоватьWatiN в ваших тестах напрямую.Почему у вас не может быть тестового проекта с кодом WatiN?Кроме того, у меня действительно есть ощущение, что вам нужно больше изучать C #.Ранее вы уже говорили, что используете C # в течение нескольких дней.

В качестве ответа на ваш вопрос вы не можете иметь ссылку на объекты, созданные вами в отдельных процессах (.NET - в отдельном домене приложений).).Вы не можете сделать что-то, как вы хотели сделать в своем предыдущем вопросе , то есть:

System.Diagnostics.Process Proc = new System.Diagnostics.Process();
Proc.StartInfo.FileName = "path_to_exe\\winformWithWebBrowserTest.exe";
Proc.Start();

WindowsFormsApplication1.Form1 form1 = new Form1();

С этим кодом вы находитесь в процессе A:

  1. Запуск процесса B.
  2. Создание объекта типа Form1 в процессе A.

Нет связи, связи или чего-либо еще между процессами A и B. Вы можете 't просто создайте объект или вызовите метод или что-то еще в процессе A, который живет в проекте B. Если вам нужно это сделать, вам нужно поискать в Google «межпроцессное взаимодействие в C #».В эти дни вы можете добавить "WCF" к вашим критериям поиска.Например, посмотрите на этот вопрос: Межпроцессное взаимодействие для Windows в C # (.NET 2.0) или Каков наилучший выбор для межпроцессного взаимодействия .NET? .Но на самом деле все не так просто, как вы хотите.По сути, это все равно что сделать процесс B сервером / хостом, а процесс A - клиентом.

РЕДАКТИРОВАТЬ после комментария OP

Если вы хотите автоматизировать только управление через веб-браузер, этоможно сделать с небольшим усилием.Вы можете попробовать что-то вроде этого:

var p = Process.Start(@"path_to_exe");

Thread.Sleep(1000); //Need to wait a while for that process to start, 
                    //and web browser control to initialize

//Use IEUtils from WatiN library
//We need to find a handle to window containing web browser control
//Maybe you will have to do some other stuff to find that window and I can't
//guarantee this will work instantly, because internally this method is enumerating
//controls on form to find web browser control
var htmlDocument = IEUtils.IEDOMFromhWnd(p.MainWindowHandle); 

//Copy from WatiN class - ShellWindows2
var SID_SWebBrowserApp = new Guid(0x0002DF05, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);

var serviceProvider = htmlDocument as WatiN.Core.Native.Windows.IServiceProvider;

object objIWebBrowser;
var guidIWebBrowser = typeof(IWebBrowser2).GUID;
serviceProvider.QueryService(ref SID_SWebBrowserApp, ref guidIWebBrowser, out objIWebBrowser);

//Stopping dialog watcher is essential
Settings.AutoStartDialogWatcher = false;
var ie = new IE(objIWebBrowser);
ie.GoTo(@"http://www.google.com");

Если вам нужно использовать диалоговое средство просмотра, вы можете переписать код из моего ответа на другой вопрос .

...