Merge pull request #1789 from bosix/1754-add-codeception

#1745 - add codeception and example tests
This commit is contained in:
Jitendra Singh 2019-12-13 15:30:51 +05:30 committed by GitHub
commit 9486f00987
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 346 additions and 458 deletions

45
.env.testing Normal file
View File

@ -0,0 +1,45 @@
APP_NAME=Bagisto
APP_ENV=local
APP_VERSION=0.1.8
APP_KEY=base64:NFtGjjFAqET6RlX3PVC/gFpzHb4jK1OxDc3cuU5Asz4=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=bagisto_test
DB_USERNAME=root
DB_PASSWORD=root
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=20
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=tls
SHOP_MAIL_FROM=
ADMIN_MAIL_TO=
fixer_api_key=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

10
codeception.yml Normal file
View File

@ -0,0 +1,10 @@
paths:
tests: tests
output: tests/_output
data: tests/_data
support: tests/_support
envs: tests/_envs
actor_suffix: Tester
extensions:
enabled:
- Codeception\Extension\RunFailed

View File

@ -36,6 +36,7 @@
},
"require-dev": {
"codeception/codeception": "3.1.*",
"barryvdh/laravel-debugbar": "^3.1",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
@ -125,6 +126,12 @@
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
],
"test": [
"set -e",
"@php artisan migrate:fresh --env=testing",
"vendor/bin/codecept run unit",
"vendor/bin/codecept run functional"
]
},
"config": {
@ -132,5 +139,6 @@
"sort-packages": true,
"optimize-autoloader": true
},
"minimum-stability": "dev"
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@ -1,32 +0,0 @@
<?php
namespace Tests\Browser;
use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ExampleTest extends DuskTestCase
{
/**
* A basic browser test example.
*
* @return void
*/
public function testBasicExample()
{
$customer = app('Webkul\Customer\Repositories\CustomerRepository');
$customer = $customer->all();
$customer = $customer->first();
$this->browse(function (Browser $browser) use($customer) {
$browser->visit('/customer/login')
->type('email', $customer->email)
->type('password', $customer->password)
->click('input[type="submit"]')
->screenshot('error');
});
}
}

View File

@ -1,41 +0,0 @@
<?php
namespace Tests\Browser\Pages;
use Laravel\Dusk\Browser;
class HomePage extends Page
{
/**
* Get the URL for the page.
*
* @return string
*/
public function url()
{
return '/';
}
/**
* Assert that the browser is on the page.
*
* @param Browser $browser
* @return void
*/
public function assert(Browser $browser)
{
//
}
/**
* Get the element shortcuts for the page.
*
* @return array
*/
public function elements()
{
return [
'@element' => '#selector',
];
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace Tests\Browser\Pages;
use Laravel\Dusk\Page as BasePage;
abstract class Page extends BasePage
{
/**
* Get the global element shortcuts for the site.
*
* @return array
*/
public static function siteElements()
{
return [
'@element' => '#selector',
];
}
}

View File

@ -1,49 +0,0 @@
<?php
namespace Tests\Browser;
use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ProductCategoryTest extends DuskTestCase
{
/**
* A basic browser test example.
*
* @return void
*/
public function testGuestAddToCart()
{
$categories = app('Webkul\Category\Repositories\CategoryRepository')->all();
$products = app('Webkul\Product\Repositories\ProductRepository')->all();
$slugs = array();
foreach ($categories as $category) {
if ($category->slug != 'root') {
array_push($slugs, $category->slug);
}
}
$slugIndex = array_rand($slugs);
$testSlug = $slugs[$slugIndex];
$testProduct = array();
foreach ($products as $product) {
$categories = $product->categories;
if ($categories->last()->slug == $testSlug) {
array_push($testProduct, ['name' => $product->name, 'url_key' => $product->url_key]);
break;
}
}
$this->browse(function (Browser $browser) use($testSlug, $testProduct) {
$browser->visit(route('shop.categories.index', $testSlug));
$browser->assertSeeLink($testProduct[0]['name']);
$browser->pause(5000);
});
}
}

View File

@ -1,2 +0,0 @@
*
!.gitignore

View File

@ -1,2 +0,0 @@
*
!.gitignore

View File

@ -1,22 +0,0 @@
<?php
namespace Tests;
use Illuminate\Contracts\Console\Kernel;
trait CreatesApplication
{
/**
* Creates the application.
*
* @return \Illuminate\Foundation\Application
*/
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Kernel::class)->bootstrap();
return $app;
}
}

View File

@ -1,48 +0,0 @@
<?php
namespace Tests;
use Laravel\Dusk\TestCase as BaseTestCase;
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
abstract class DuskTestCase extends BaseTestCase
{
use CreatesApplication;
/**
* Prepare for Dusk test execution.
*
* @beforeClass
* @return void
*/
public static function prepare()
{
static::startChromeDriver();
}
/**
* Create the RemoteWebDriver instance.
*
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
*/
protected function driver()
{
$options = (new ChromeOptions)->addArguments([
'--disable-gpu',
'--headless',
'--no-sandbox'
]);
return RemoteWebDriver::create(
'http://localhost:9515/', DesiredCapabilities::chrome()
);
// return RemoteWebDriver::create(
// 'http://localhost:9515', DesiredCapabilities::chrome()->setCapability(
// ChromeOptions::CAPABILITY, $options
// )
// );
}
}

View File

@ -1,124 +0,0 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Auth;
use Crypt;
use App;
use Faker\Generator as Faker;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Webkul\Customer\Repositories\CustomerRepository as Customer;
class AuthTest extends TestCase
{
protected $customer;
/**
* To check if the customer can view the login page or not
*
* @return void
*/
public function testCustomerLoginPage()
{
config(['app.url' => 'http://prashant.com']);
$response = $this->get('/customer/login');
$response->assertSuccessful();
$response->assertViewIs('shop::customers.session.index');
}
public function testCustomerResgistrationPage()
{
config(['app.url' => 'http://prashant.com']);
$response = $this->get('/customer/register');
$response->assertSuccessful();
$response->assertViewIs('shop::customers.signup.index');
}
public function testCustomerRegistration() {
$faker = \Faker\Factory::create();
$allCustomers = array();
$customers = app(Customer::class);
$created = $customers->create([
'first_name' => explode(' ', $faker->name)[0],
'last_name' => explode(' ', $faker->name)[0],
'channel_id' => core()->getCurrentChannel()->id,
'gender' => $faker->randomElement($array = array ('Male','Female', 'Other')),
'date_of_birth' => $faker->date($format = 'Y-m-d', $max = 'now'),
'email' => $faker->email,
'password' => bcrypt('12345678'),
'is_verified' => 1
]);
$this->assertEquals($created->id, $created->id);
}
public function testCustomerLogin()
{
config(['app.url' => 'http://prashant.com']);
$customers = app(Customer::class);
$customer = $customers->findOneByField('email', 'john@doe.net');
$response = $this->post('/customer/login', [
'email' => $customer->email,
'password' => '12345678'
]);
$response->assertRedirect('/customer/account/profile');
}
/**
* Test that customer cannot login with the wrong credentials.
*/
public function willNotLoginWithWrongCredentials()
{
$customers = app(Customer::class);
$customer = $customers->findOneByField('email', 'john@doe.net');
$response = $this->from(route('login'))->post(route('customer.session.create'),
[
'email' => $customer->email,
'password' => 'wrongpassword3428903mlndvsnljkvsd',
]);
$this->assertGuest();
}
/**
* Test to confirm that customer cannot login if user does not exist.
*/
public function willNotLoginWithNonexistingCustomer()
{
$response = $this->post(route('customer.session.create'), [
'email' => 'fiaiia9q2943jklq34h203qtb3o2@something.com',
'password' => 'wrong-password',
]);
$this->assertGuest();
}
/**
* To test that customer can logout
*/
public function allowsCustomerToLogout()
{
$customer = auth()->guard('customer')->user();
$this->get(route('customer.session.destroy'));
$this->assertGuest();
}
}

View File

@ -1,88 +0,0 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Http\Request;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Webkul\Category\Repositories\CategoryRepository;
class GeneralTest extends TestCase
{
/**
* Test for home page
*
* @return void
*/
public function testHomePage()
{
config(['app.url' => 'http://prashant.com']);
$response = $this->get('/');
$response->assertStatus(200);
}
/**
* Test for customer login
*
* @return void
*/
public function testCustomerLoginPage()
{
config(['app.url' => 'http://prashant.com']);
$response = $this->get('/customer/login');
$response->assertStatus(200);
}
/**
* Test for categories page
*
* @return void
*/
public function testCategoriesPage()
{
$categoryUrlSlug = 'marvel-figurines';
config(['app.url' => 'http://prashant.com']);
$response = $this->get("/categories/{$categoryUrlSlug}");
$response->assertStatus(200);
}
/**
* Test for customer registration page
*
* @return void
*/
public function testCustomerRegistrationPage()
{
// config(['app.url' => 'http://127.0.0.1:8000']);
$response = $this->get("/customer/register");
$response->assertStatus(200);
}
/**
* Test for checkout's cart page
*
* @return void
*/
public function testCartPage()
{
// config(['app.url' => 'http://127.0.0.1:8000']);
$response = $this->get("/checkout/cart");
$response->assertStatus(200);
}
}

View File

@ -1,10 +0,0 @@
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
}

View File

@ -1,19 +0,0 @@
<?php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$this->assertTrue(true);
}
}

0
tests/_data/.gitkeep Normal file
View File

2
tests/_output/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,26 @@
<?php
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method void pause()
*
* @SuppressWarnings(PHPMD)
*/
class AcceptanceTester extends \Codeception\Actor
{
use _generated\AcceptanceTesterActions;
/**
* Define custom actions here
*/
}

View File

@ -0,0 +1,61 @@
<?php
use Illuminate\Routing\RouteCollection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Webkul\User\Models\Admin;
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method void pause()
*
* @SuppressWarnings(PHPMD)
*/
class FunctionalTester extends \Codeception\Actor
{
use _generated\FunctionalTesterActions;
/**
* Define custom actions here
*/
/**
* Login as default administrator
*/
public function loginAsAdmin(): void
{
$I = $this;
Auth::guard('admin')->login($I->grabRecord(Admin::class, ['email' => 'admin@example.com']));
$I->seeAuthentication('admin');
}
/**
* Go to a specific route and check if admin guard is applied on it
*
* @param string $name name of the route
* @param array|null $params params the route will be created with
*/
public function amOnAdminRoute(string $name, array $params = null): void
{
$I = $this;
$I->amOnRoute($name, $params);
$I->seeCurrentRouteIs($name);
/** @var RouteCollection $routes */
$routes = Route::getRoutes();
$middlewares = $routes->getByName($name)->middleware();
$I->assertContains('admin', $middlewares, 'check that admin middleware is applied');
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Helper;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
class Acceptance extends \Codeception\Module
{
}

View File

@ -0,0 +1,10 @@
<?php
namespace Helper;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
class Functional extends \Codeception\Module
{
}

View File

@ -0,0 +1,10 @@
<?php
namespace Helper;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
class Unit extends \Codeception\Module
{
}

View File

@ -0,0 +1,26 @@
<?php
/**
* Inherited Methods
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method void pause()
*
* @SuppressWarnings(PHPMD)
*/
class UnitTester extends \Codeception\Actor
{
use _generated\UnitTesterActions;
/**
* Define custom actions here
*/
}

2
tests/_support/_generated/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,13 @@
# Codeception Test Suite Configuration
#
# Suite for acceptance tests.
# Perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.
actor: AcceptanceTester
modules:
enabled:
- PhpBrowser:
url: http://localhost
- \Helper\Acceptance
step_decorators: ~

View File

@ -0,0 +1,20 @@
# Codeception Test Suite Configuration
#
# Suite for functional tests
# Emulate web requests and make application process them
# Include one of framework modules (Symfony2, Yii2, Laravel5) to use it
# Remove this suite if you don't use frameworks
actor: FunctionalTester
modules:
enabled:
# add a framework module here
- \Helper\Functional
- Asserts
- Laravel5:
environment_file: .env.testing
run_database_migrations: true
run_database_seeder: true
database_seeder_class: DatabaseSeeder
step_decorators: ~

View File

@ -0,0 +1,70 @@
<?php
namespace Tests\Functional\Shop;
use Faker\Factory;
use Faker\Generator;
use FunctionalTester;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductFlat;
class ProductControllerCest
{
/** @var Generator */
private $faker;
public function _before(FunctionalTester $I)
{
$this->faker = Factory::create();
}
public function testCreate(FunctionalTester $I)
{
$I->loginAsAdmin();
$I->amOnAdminRoute('admin.catalog.products.index');
$I->click(__('admin::app.catalog.products.add-product-btn-title'), '//*[contains(@class, "page-action")]');
$I->seeCurrentRouteIs('admin.catalog.products.create');
$I->click(__('admin::app.catalog.products.save-btn-title'), '//*[contains(@class, "page-action")]');
$I->seeFormHasErrors();
$testSku = $this->faker->uuid;
$I->selectOption('//select[@id="attribute_family_id"]', 'Default');
$I->fillField('//input[@id="sku"]', $testSku);
$I->click(__('admin::app.catalog.products.save-btn-title'), '//*[contains(@class, "page-action")]');
$I->dontSeeFormErrors();
$I->seeCurrentRouteIs('admin.catalog.products.edit');
$I->seeRecord(Product::class, ['sku' => $testSku]);
$I->click(__('admin::app.catalog.products.save-btn-title'), '//*[contains(@class, "page-action")]');
$I->seeFormHasErrors();
$testName = $this->faker->name;
$testUrlKey = $testName;
$testDescription = $this->faker->sentence;
$testDescriptionShop = $this->faker->sentence;
$testPrice = $this->faker->randomFloat(2, 1, 100);
$testWeight = $this->faker->numberBetween(1, 20);
$I->fillField('//input[@id="name"]', $testName);
$I->fillField('//input[@id="url_key"]', $testUrlKey);
$I->fillField('//textarea[@id="description"]', $testDescription);
$I->fillField('//textarea[@id="short_description"]', $testDescriptionShop);
$I->fillField('//input[@id="price"]', $testPrice);
$I->fillField('//input[@id="weight"]', $testWeight);
$I->click(__('admin::app.catalog.products.save-btn-title'), '//*[contains(@class, "page-action")]');
$I->dontSeeFormErrors();
$I->seeCurrentRouteIs('admin.catalog.products.index');
$product = $I->grabRecord(Product::class, ['sku' => $testSku]);
$I->seeRecord(ProductFlat::class, [
'sku' => $testSku,
'name' => $testName,
'description' => $testDescription,
'short_description' => $testDescriptionShop,
'url_key' => $testUrlKey,
'price' => $testPrice,
'weight' => $testWeight,
'product_id' => $product->id,
]);
}
}

17
tests/unit.suite.yml Normal file
View File

@ -0,0 +1,17 @@
# Codeception Test Suite Configuration
#
# Suite for unit or integration tests.
actor: UnitTester
modules:
enabled:
- Asserts
- Filesystem
- \Helper\Unit
- Laravel5:
environment_file: .env.testing
run_database_migrations: true
run_database_seeder: true
database_seeder_class: DatabaseSeeder
step_decorators: ~

View File

@ -0,0 +1,15 @@
<?php
namespace Tests\Unit\Product\Helpers;
use UnitTester;
use Webkul\Product\Helpers\ProductType;
class ProductTypeCest
{
public function testHasVariants(UnitTester $I)
{
$I->assertTrue(ProductType::hasVariants('configurable'));
$I->assertFalse(ProductType::hasVariants('simple'));
}
}