I'm using Test complete for automation. I create class : "Common" with code :
function Read_Excel_Login(){
var Driver1 = DDT.ExcelDriver("C:/Users/NVA/Downloads/leave.xls","login",true);
}
function Login()
{
if( Driver1.Value(3)==2)
{
page = Aliases.browser.pageHrmtestSpsSymfonyWebIndexPhp2;
page.Wait(5000);
}
else
{
page= Aliases.browser.pageHrmtestSpsSymfonyWebIndexPhp;
page.Wait(5000);
}
page.contentDocument.Script.$("#txtUsername").val(Driver1.Value(0)).change();
page.contentDocument.Script.$("#txtPassword").val(Driver1.Value(1)).change();
page.contentDocument.Script.$("#btnLogin").click();
}
I Create other class : "Main" for login user and call class : "common" with code:
var Common = require("Common");
function Main()
{
Common.Read_Excel_Login();
while(!Driver1.EOF())
{
Common.Login();
Driver1.Next();
}
}
Error appear after run:
ReferenceError
Driver1 is not defined
How to fix this problem ? Thanks.
If you put a breakpoint at the start of your code and step through it, it might help you find the issue.
The issue is that you've declared Driver1 in the function Read_Excel_Login() and then that function goes out of scope and you reference Driver1 in the function Login() where it's not defined.
I would define Driver1 in Main() and then have Read_Excel_Login() return a driver instance. Then you can pass Driver1 to Login() where it can be used.
function Read_Excel_Login()
{
return DDT.ExcelDriver("C:/Users/NVA/Downloads/leave.xls", "login", true);
}
function Main()
{
var ExcelDriver = Common.Read_Excel_Login();
while(!ExcelDriver.EOF())
{
Common.Login(ExcelDriver);
ExcelDriver.Next();
}
}
function Login(ExcelDriver) { ... }
I also changed the name of the driver to be more specific, ExcelDriver instead of Driver1.
It's been a long time since I've done anything with TestComplete so I think this syntax is mostly correct.
Related
I have a Controller that has a dependency with BillingService, and BillingService has another dependency on UserService.
I need to call the Controller method getPlans and in this call I need to mock two functions:
loadPlans that is inside BillingService
getUsage that is in UserService
This is the full example:
class BillingPlanController
{
public function __construct(private BillingPlanService $billingPlanService)
{
}
public function getPlans()
{
$plans = $this->billingPlanService->getPlans();
//
}
}
class BillingPlanService
{
public function __construct(private UserService $userService)
{
}
public function getPlans()
{
$plans = $this->loadPlans();
$user = auth()->user();
$usage = $this->userService->getUsage(user); // DO SOMETHING, NEED TO MOCK .. HOW ?
}
public function loadPlans()
{
// DO SOMETHING, NEED TO MOCK .. HOW ?
}
}
At the end, in my test i simply call:
getJson(action([BillingPlanController::class, "getPlans"]));
In other tests, I'm able to mock a single Service, but in this scenario, I don't know how to write the mocks.
Sorry if I don't provide any "tries", but I really don't know how I can do that.
UPDATE
I tried to use partialMock and mock, but I get this error (when getUsage is called) - partialMock is used because i just need to mock a single function:
Typed property App\Modules\Billing\Services\BillingPlanService::$userService must not be accessed before initialization
$this->mock(UserService::class, function ($mock) {
$mock->shouldReceive("getUsage")->andReturn([]);
});
$this->partialMock(BillingPlanService::class, function ($mock) {
$mock->shouldReceive("loadPlans")->andReturn([]);
});
getJson(action([BillingPlanController::class, "getPlans"]));
Your exception in your partial mock, is because when you mock the BillingPlanService you do not intilize the userService due to it being a mock. You can simply set it on the mock and i think it should work in your context.
$userServiceMock = $this->mock(UserService::class, function ($mock) {
$mock->shouldReceive("getUsage")->andReturn([]);
});
$this->partialMock(BillingPlanService::class, function ($userServiceMock) use ($userServiceMock) {
$mock->set('userService', $userServiceMock);
$mock->shouldReceive("loadPlans")->andReturn([]);
});
I have a cake shell, say DemoShell. And, from a method 'method1', I want to create another process which executes 'method2' of DemoShell. How can that be done?
class DemoShell extends AppShell {
// some code
private function method1() {
// some code
$success = $this->dispatchShell('Demo', 'method2', $params);
// some more code
}
private function method2() {
// some code to do something and return boolean value
}
}
I tried this, but method2 isn't getting called.
Is there anyone here used CIUnit?
Having trouble understanding it. T_T.
What I'm doing is pretty simple
E.g
I have a controller method myphp()
function myphp()
{
echo 'boom';
}
CI Unit Testing:
public function setUp()
{
// Set the tested controller
$this->CI = set_controller('home');
// date_default_timezone_set('America/Los_Angeles');
}
function testMyPhp()
{
$this->CI->myphp();
$out = output();
var_dump($out); //return empty eventhough function myphp is returning a string ('boom')
}
What happening.?? I just want to test whether I can fetch the output of my method myphp.
I have a Zend Framework controller with an editAction().
class WidgetController extends BaseController
{
public function editAction()
{
//code here
}
}
This controller extends a base controller which checks if the user is logged in before allowing the user to edit a record.
class BaseController extends Zend_Controller_Action
{
public function init()
{
if ($this->userNotLoggedIn()) {
return $this->_redirect('/auth/login');
}
}
}
However, now that I am performing an AJAX request, I will be sending a JSON response back, so a redirect will no longer work. I need to stop further controller execution so I can immediately send a response:
class BaseController extends Zend_Controller_Action
{
public function init()
{
if ($this->userNotLoggedIn()) {
if ($this->_request->isXmlHttpRequest()) {
$jsonData = Zend_Json::encode(array('error'=>'You are not logged in!'));
$this->getResponse()
->setHttpResponseCode(401)
->setBody($jsonData)
->setHeader('Content-Type', 'text/json');
//now stop controller execution so that the WidgetController does not continue
} else {
return $this->_redirect('/auth/login');
}
}
}
}
How can I stop controller execution?
I would define the user not being logged in and trying to make an XMLHTTPRequest as an exceptional state and let the error handler deal with it by throwing an exception (which stops dispatching of the current action). That way you are also able to handle other kinds of exceptions that might happen:
class BaseController extends Zend_Controller_Action
{
public function init()
{
if ($this->userNotLoggedIn()) {
if ($this->_request->isXmlHttpRequest()) {
throw new Exception('You are not logged in', 401);
} else {
return $this->_redirect('/auth/login');
}
}
}
}
class ErrorController extends Zend_Controller_Action
{
public function errorAction()
{
$errors = $this->_getParam('error_handler');
$exception = $errors->exception;
if ($this->_request->isXmlHttpRequest()) {
$jsonData = Zend_Json::encode($exception);
$jsonData = Zend_Json::encode(array('error'=> $exception->getMessage()));
$isHttpError = $exception->getCode() > 400 && $exception->getCode();
$code = $isHttpError ? $exception->getCode() : 500;
$this->getResponse()
->setHttpResponseCode($code)
->setBody($jsonData)
->setHeader('Content-Type', 'application/json');
} else {
// Render error view
}
}
}
I can think of many ways to stop the controller at this point in your code.
//now stop controller execution so that the WidgetController does not continue
For one, you can replace that line with this the following:
$this->getResponse()->sendResponse();
exit;
That may not be the cleanest but gets the job done rather nicely. The other option is going to be to change the action of the request in the init and let another action handle it. Replace that line with this:
$this->getRequest()->setActionName('invalid-user');
Because your already inside the dispatcher, it's going to run an action inside your action class whether you want it to or not. Trying to change the request in preDispatch will do nothing to change this dispatch. It's determined at this point to run an action inside your class. So, make an action to handle it.
public function invalidUserAction()
{
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
}
For more information see Zend_Controller_Dispatcher_Standard::dispatch.
This is my Unit Test class
<?
require_once '../simpletest/unit_tester.php';
require_once '../simpletest/reporter.php';
class Academic extends UnitTestCase
{
function setUp()
{
}
function tearDown()
{
}
function testAc1()
{
}
function testAc4()
{
}
function testAc7()
{
}
}
$test = new Academic();
$test->run(new HtmlReporter());
?>
When I run this script all methods viz., testAc1, testAc4, testAc7 etc are run.
Is there a way to execute just a single method ?
Thanks,
Shikhar
After digging through the SimpleTest source a bit, I have found the easiest way is to override the test's getTests() method as follows,
require_once('simpletest/autorun.php');
class Academic extends UnitTestCase
{
# ..
function testAc7()
{
}
function getTests()
{
return array("testAc7");
}
}
Here, simply including autorun.php as per usual, only the tests named in getTests() will be run.