Здравствуйте! я программирую совсем недавно на php. Так вот столкнулась с такой проблемой: нужно в статической функции вызвать нестатический метод. Выглядит это примерно так: Код (Text): public static function LoginUser ($log, $pass) { $this->type("login", $log); $this->type("pass", $pass); $this->click($this->inLocation); } насколько я знаю, методы type и click прописаны как нестатические где то в исходном коде, и они наследуются моим классом, в котором создаю функцию LoginUser. ошибка у меня такая: Using $this when not in object context Скажите пожалуйста, кто знает, можно ли как нибудь вызвать нестатический метод в статической функции?
self::type("login", $log) Но у тебя не будет никакого $this->inLocation. Параметр inLocation будет только у объекта. Короче говоря, скорее всего ошибка в архитектуре.... Т.е. если методы используются как нестатические, в наследуемом классе тоже надо использовать их как нестатические
может тогда просто есть другой выход из ситуации? ситуация такая: есть класс "PHPUnit_Extensions_SeleniumTestCase", который является n-ным наследников других классов. там очень большая иерархия исходников. Так вот я наследую этот класс при написании своих программ (назовем их "Тесты"), так как где то там находятся методы, которые мне нужно использовать типа type(), click() и т.д. Из за того, что у меня многие методы повторяются при написании своих программ (Тестов), я вынесла эти методы в отдельный класс (назовем его "Технический"), который тоже является наследником "PHPUnit_Extensions_SeleniumTestCase". Если я в своем Тесте создам экземпляр класса Технический и вызову нужный метод вот так: $my_class = new Technical(); $my_class->LoginUser(); то у меня появится ошибка, потому что и Тест и Технический являются наследниками класса "PHPUnit_Extensions_SeleniumTestCase", который своим конструктором автоматически создает сессию. Получается сессия внутри сессии и ошибка. Чтоб не вызывать конструктор я решила сделать методы внутри технического класса статическими и вызывать их вот так: Technical::LoginUser(); Ну и собственно ошибка, которая получилась в результате этого, описана выше
Jenka156 я бы сделал так - унаследовал от PHPUnit_Extensions_SeleniumTestCase технический класс, в которой бы вынес повторяющиеся действия Пример PHP: <?php class MyTestCase extends PHPUnit_Extensions_SeleniumTestCase { public function login() { $this->assertElementPresent('name=ContactForm[name]'); $this->type('name=ContactForm[name]','tester'); $this->type('name=ContactForm[email]','tester@example.com'); $this->type('name=ContactForm[subject]','test subject'); $this->click("//input[@value='Submit']"); } //и т.д. } А остальные тесты наследовал бы от MyTestCase PHP: <?php class TestUserModel extends MyTestCase { public function doSomething() { $this->login(); //тут наши специфические действия } //и т.д. }
у меня была такая мысль, но тут появилась заминка. Вот пример: есть класс теста по созданию подразделений и есть класс теста по созданию пользователей Без подразделений я не могу создать пользователей, а по техническому заданию у меня каждый тест должен заканчиваться удалением всех данных, которые были созданы в процессе. Поэтому в тесте по созданию пользователей мне нужно будет вызвать методы для создания подразделений и использовать переменные, которые хранятся только в классе по подразделениям. Оба эти класса могут наследовать класс Технический (где описаны более общие методы типа loginUser), но мне может понадобится вызов более специфических методов. А выносить это все в технический класс будет плохо, потому что получится каша
Согласен, так будет каша. Но тут вопрос - PHP: Без подразделений я не могу создать пользователей - а разве нельзя в методе setUp() теста пользователей внести в базу данных тестовые подразделения, а в tearDown() их очистить? Обязательно их через Selenium забивать?
Jenka156 Тогда можно попробовать написать свои классы со статическими методами и передавать туда экземпляр теста. Пример PHP: <?php class Technical { public static function login($object) { $object->assertElementPresent('name=ContactForm[name]'); $object->type('name=ContactForm[name]','tester'); $object->type('name=ContactForm[email]','tester@example.com'); $object->type('name=ContactForm[subject]','test subject'); $object->click("//input[@value='Submit']"); } } Тогда внутри теста будет что-то типа такого PHP: <?php class MyTestCase extends PHPUnit_Extensions_SeleniumTestCase { public function doSomething() { Technical::login($this); //some other actions } }