SlideShare a Scribd company logo
1 of 104
Download to read offline
Introduction aux tests de recette automatisés
Avec l'extension Drupal pour Behat
didier.boff@ows.fr
B2F @ drupal.org
https://github.com/B2F
http:///twitter.com/zenelse
Les joies du test
Quand mon collègue avance sans plan de test
http://lesjoiesdutest.tumblr.com
Plan
● Retour d'expérience
○ Campus France
○ Divers outils démodés
Plan
● Retour d'expérience
○ Campus France
○ Divers outils démodés
● Méthodologie
○ BDD, Gherkin
Plan
● Retour d'expérience
○ Campus France
○ Divers outils démodés
● Méthodologie
○ BDD, Gherkin
● Développement
○ Behat/Mink
○ MinkExtension (démo)
○ DrupalExtension (démo)
Retour d'expérience
www.campusfrance.org
● Migration Drupal 6 -> 7
Retour d'expérience
www.campusfrance.org
● Migration Drupal 6 -> 7
● 100 sites, domain access
● multilingues
Retour d'expérience
www.campusfrance.org
● Migration Drupal 6 -> 7
● 100 sites, domain access
● multilingues
Quels tests ?
Retour d'expérience
Selenium
API
● click
● type
● select
● addSelection
● submit
● ... http://release.seleniumhq.org/selenium-
core/
Retour d'expérience
Selenium
IDE
Retour d'expérience
?
Test automatisé
Selenium
IDE
Retour d'expérience
Selenium
IDE
?
Test automatisé
Multidomaine
Retour d'expérience
Selenium
IDE
?AJAX
Multidomaine
Test automatisé
Retour d'expérience
Selenium Server
http://docs.seleniumhq.org/download/
java -jar selenium-server-standalone-<version-number>.jar
http://selenium.googlecode.com/files/selenium-server-standalone-2.33.0.jar
Retour d'expérience
Selenium Server
+ PHPUnit
PHPUnit_Extensions_SeleniumTestCase
Retour d'expérience
Selenium Server
+ PHPUnit
https://github.com/B2F/ows-phpunit
class OWSeleniumTestCase extends
PHPUnit_Extensions_SeleniumTestCase {
public function __construct($name = NULL, array $data = array(),
$dataName = '') {
Retour d'expérience
Selenium Server
+ PHPUnit
+ IDE
Retour d'expérience
Selenium Server
+ PHPUnit
+ IDE
+
Selenium IDE: PHP Formatters
https://github.com/brokenthumbs/PHP-Formatter
Retour d'expérience
Selenium Server
+ PHPUnit
+ IDE
+
Selenium IDE: PHP Formatters
https://github.com/brokenthumbs/PHP-Formatter
https://github.com/B2F/PHP-Formatter
Les joies du test
Quand je fais un test un peu trop compliqué pour un truc
tout simple
http://lesjoiesdutest.tumblr.com
Les joies du test
Quand je fais un test un peu trop
compliqué pour un truc tout simple ?
Les joies du test
Quand je fais un test un peu trop
compliqué pour un truc tout simple
Les joies du test
Quand je fais un test un peu trop
compliqué pour un truc tout simple
19 content types
Les joies du test
Quand je fais un test un peu trop
compliqué pour un truc tout simple
...
Méthodologie
● Behavior Driven Development (BDD)
Méthodologie
● Behavior Driven Development (BDD)
DrupalCon Portland 2013: BEHAT, BEHAVIORAL-
DRIVEN DEVELOPMENT AND SELENIUM IN DRUPAL
Ryan Weaver
https://portland2013.drupal.org
Méthodologie
● Gherkin
Méthodologie
● Gherkin
● Feature Suite de tests
Méthodologie
● Gherkin
● Feature
○ Scenario Test
Méthodologie
● Gherkin
● Feature
○ Scenario
■ Given
● And...
Contexte
Méthodologie
● Gherkin
● Feature
○ Scenario
■ Given
● And...
Contexte
Given I am on "/restaurants"
Méthodologie
● Gherkin
● Feature
○ Scenario
■ Given
● And...
■ When
● And...
Évènements
Méthodologie
● Gherkin
● Feature
○ Scenario
■ Given
● And...
■ When
● And...
Évènements
And I enter "Vietnam" for "pays"
And I enter "Bo Bun" for "plats"
And I enter "Paris 13" for "lieu"
Méthodologie
● Gherkin
● Feature
○ Scenario
■ Given
● And...
■ When
● And...
■ Then
● And...
Résultats
Then I should see the text "Pho Bida"
Opened Blackbox
● Cucumber
Gherkin + Ruby
Opened Blackbox
● Cucumber
=
Gherkin + Ruby
Opened Blackbox
● Cucumber
Gherkin + Ruby ?
Opened Blackbox
● Cucumber
Gherkin + PHP
Opened Blackbox
● Behat
http://behat.org/
=
Gherkin + PHP
Opened Blackbox
http://behat.org/
<?php
use BehatBehatContextBehatContext
class FeatureContext extends BehatContext
{
// /**
// * @Given /^I have done something with "([^"]*)"$/
// */
// public function iHaveDoneSomethingWith($argument)
// {
// doSomethingWith($argument);
// }
}
● Behat: ça fait quoi ?
Opened Blackbox
http://behat.org/
<?php
use BehatBehatContextBehatContext
class FeatureContext extends BehatContext
{
// /**
// * @Given /^I have done something with "([^"]*)"$/
// */
// public function iHaveDoneSomethingWith($argument)
// {
// doSomethingWith($argument);
// }
}
● Behat: ça fait quoi ?
Opened Blackbox
● Mink
Web acceptance testing
http://mink.behat.org/
Opened Blackbox
● Mink: drivers
$driver = new BehatMinkDriverZombieDriver();
http://mink.behat.org/
Opened Blackbox
● Mink: drivers
$driver = new BehatMinkDriverSahiDriver('firefox');
http://mink.behat.org/
Opened Blackbox
● Mink: drivers
$driver = new BehatMinkDriverGoutteDriver();
http://mink.behat.org/
Opened Blackbox
● Mink: drivers
$client = new SeleniumClient($host, $port);
$driver = new BehatMinkDriverSeleniumDriver(
'firefox', 'base_url', $client
);
http://mink.behat.org/
Opened Blackbox
● Mink: session
// init session:
$session = new BehatMinkSession($driver);
// start session:
$session->start();
http://mink.behat.org/
$session->visit('http://paris2013.drupalcamp.fr');
Opened Blackbox
● Mink: méthodes
$page = $session->getPage();
$element = $page->find('css', 'a#selector');
$element->getText();
http://mink.behat.org/
Opened Blackbox
● Mink: méthodes
$page = $session->getPage();
$element = $page->find('css', 'a#selector');
$element->getText();
http://mink.behat.org/
Développement
● En pratique
http://mink.behat.org/
Behat + Mink ?
Développement
● Mink extension
http://mink.behat.org/
=
Behat + Mink
Développement
● Mink extension
http://mink.behat.org/
STEPS
Développement
● Mink extension
http://mink.behat.org/
Given /^(?:|I )am on (?:|the )homepage$/
When /^(?:|I )go to (?:|the )homepage$/
Given /^(?:|I )am on "(?P<page>[^"]+)"$/
When /^(?:|I )go to "(?P<page>[^"]+)"$/
When /^(?:|I )reload the page$/
When /^(?:|I )move backward one page$/
When /^(?:|I )move forward one page$/
When /^(?:|I )press "(?P<button>(?:[^"]|")*)"$/
When /^(?:|I )follow "(?P<link>(?:[^"]|")*)"$/
When /^(?:|I )fill in "(?P<field>(?:[^"]|")*)" with "(?P<value>(?:[^"]|")*)"$/
When /^(?:|I )fill in "(?P<field>(?:[^"]|")*)" with:$/
When /^(?:|I )fill in "(?P<value>(?:[^"]|")*)" for "(?P<field>(?:[^"]|")*)"$/
When /^(?:|I )fill in the following:$/
When /^(?:|I )select "(?P<option>(?:[^"]|")*)" from "(?P<select>(?:[^"]|")*)"$/
When /^(?:|I )additionally select "(?P<option>(?:[^"]|")*)" from "(?P<select>(?:[^"]|")*)"$/
...
bin/behat -dl
Développement
● Mink extension
http://mink.behat.org/
Presses button with specified id|name|title|alt|value.
@When /^(?:|I )press "(?P<button>(?:[^"]|")*)"$/
Clicks link with specified id|title|alt|text.
@When /^(?:|I )follow "(?P<link>(?:[^"]|")*)"$/
Behat/MinkExtension/Context/MinkContext.php
Développement
Installation
http://docs.behat.org/#cookbook
Developing Web Applications with Behat and Mink
Développement
Installation
composer.json
{
"require": {
"behat/behat": "2.4.*@stable",
"behat/mink": "1.4.*@stable",
"behat/mink-extension": "*",
"behat/mink-goutte-driver": "*",
"behat/mink-selenium2-driver": "*"
},
"minimum-stability": "dev",
"config": {
"bin-dir": "bin/"
}
} http://docs.behat.org/cookbook/behat_and_mink.html
Développement
Installation
$ curl http://getcomposer.org/installer | php
$ php composer.phar install
http://docs.behat.org/cookbook/behat_and_mink.html
Développement
Installation
$ ls
bin composer.json composer.lock composer.phar vendor
http://docs.behat.org/cookbook/behat_and_mink.html
Développement
Installation
$ bin/behat --init
-> features/
Développement
Installation: suites de tests
features/{name}.feature
Feature: un exemple
Quelques steps pour illustrer une feature
Scenario: vérification qu'un lien est présent
Given I am at "/home"
When I click "Se connecter"
Then I should see "login"
Développement
Installation: customisation
$ bin/behat --init
-> features/bootstrap/FeatureContext.php
Développement
Installation: customisation
# features/bootstrap/FeatureContext.php
/**
* Features context.
*/
class FeatureContext extends BehatContext
{
...
Développement
Installation: customisation
# features/bootstrap/FeatureContext.php
/**
* Features context.
*/
class FeatureContext extends BehatContext
{
...
Développement
Installation: customisation
# features/bootstrap/FeatureContext.php
/**
* Features context.
*/
class FeatureContext extends MinkContext
{
...
Développement
Installation: subcontexts
# features/bootstrap/FeatureContext.php
use BehatMinkExtensionContextRawMinkContext;
use BehatMinkExtensionContextMinkContext;
class FeatureContext extends RawMinkContext
{
public function __construct(array $parameters)
{
$this->useContext('mink', new MinkContext);
}
}
http://extensions.behat.org/mink/
Développement
Installation: subcontexts
# features/bootstrap/FeatureContext.php
use BehatMinkExtensionContextRawMinkContext;
use BehatMinkExtensionContextMinkContext;
class FeatureContext extends RawMinkContext
{
public function __construct(array $parameters)
{
$this->useContext('mink', new MinkContext);
}
}
http://extensions.behat.org/mink/
Développement
● Mink steps
When will this be over ?
http://mink.behat.org/
Développement
● Mink steps
When I hover the element ?
/**
* @When /^I hover "([^"]*)"$/
*/
public function iHover($cssId)
{
http://mink.behat.org/
When will this be over ?
Développement
● Mink steps
/**
* @When /^I hover "([^"]*)"$/
*/
public function iHover($cssId)
{
$page = $this->getSession()->getPage();
$element = $page->find('css', $cssId);
http://mink.behat.org/api/behat/mink/element/nodeelement.html
Développement
● Mink steps
public function iHover($cssId)
{
$page = $this->getSession()->getPage();
$element = $page->find('css', $cssId);
if (null === $element) {
throw new ElementNotFoundException($this->getSession(), 'element', 'css', $
}
http://mink.behat.org/api/behat/mink/element/nodeelement.html
Développement
● Mink steps
__construct(Session session, string type, string selector, string locator)
And I hover "a[title='abcdefghi']" # FeatureContext::iHover()
Element matching css "a[title='abcdefghi']" not found.
throw new ElementNotFoundException
($this->getSession(), 'element', 'css', $cssId);
http://mink.behat.org/api/behat/mink/element/nodeelement.html
Développement
● Mink steps
public function iHover($cssId)
{
$page = $this->getSession()->getPage();
$element = $page->find('css', $cssId);
if (null === $element) {
throw new ElementNotFoundException($this->getSession(), 'element', 'css', $cssId
}
$element->mouseOver();
http://mink.behat.org/api/behat/mink/element/nodeelement.html
Développement
● Mink steps
public function iHover($cssId)
{
$page = $this->getSession()->getPage();
$element = $page->find('css', $cssId);
if (null === $element) {
throw new ElementNotFoundException($this->getSession(), 'element', 'css', $cssId
}
$element->mouseOver();
Attention: Selenium supporte le
mouseOver Javascript only :(
http://mink.behat.org/api/behat/mink/element/nodeelement.html
Développement
● Mink steps - AJAX
/**
* Waits some time or until JS condition turns true.
*
* @param integer $time time in milliseconds
* @param string $condition JS condition
*/
public function wait($time, $condition = 'false')
{
$this->driver->wait($time, $condition);
}
http://mink.behat.org/api/source/behat/mink/session.php.html
Développement
● Mink steps - AJAX
/**
* @When /^I wait (?P<timing>d+)sec$/
*/
public function iWaitNSec($timing) {
$this->getSession()->wait($timing*1000);
}
http://mink.behat.org/api/source/behat/mink/session.php.html
Développement
● Mink steps - AJAX
/**
* @When /^I wait (?P<timing>d+)sec$/
*/
public function iWaitNSec($timing) {
$this->getSession()->wait($timing*1000);
}
http://mink.behat.org/api/source/behat/mink/session.php.html
Développement
Démo
bin/behat features/demo.feature
Développement
Démo: colored output
bin/behat --ansi features/demo.feature
behat arguments: http://docs.behat.org/guides/6.cli.html
Développement
● OwsContext
https://github.com/B2F/OwsContext
public function iHover($cssId)
public function iWaitNsec($timing)
public function iClickTheElementMatching($selector)
Développement
● OwsContext
https://github.com/B2F/OwsContext
+ (experimental)
public function iWaitNSecForTheText($timing, $text)
public function iSwitchToTheIframeNamed($iframe)
public function iSwitchBackFromIframe()
Développement
Configuration
# behat.yml
default:
extensions:
BehatMinkExtensionExtension:
base_url: http://google.fr
goutte: ~
selenium2: ~
Développement
Configuration
● AJAX
@javascript
Scenario: vérification qu'un lien est présent
Given I am at "/home"
When I follow "my account"
Then I should see "my page title"
Développement
Configuration
● Profiles = overrides
# behat.yml
default:
...
custom:
extensions:
BehatMinkExtensionExtension:
base_url: http://another-url.com
Développement
Configuration
● Profiles
# bin/behat --profile=custom features/tests.feature
Développement
Configuration
● Filtres
# behat.yml
custom:
...
extensions:
...
filters:
tags: "@custom-filter"
Développement
Configuration
● Filtres
@javascript @custom-filter
Scenario: vérification qu'un lien est présent
Given I am at "/home"
When I hover "Se connecter"
Then I wait 1sec for the text "login"
Développement
● Drupal Extension
https://drupal.org/project/drupalextension
Développement
● Drupal Extension
/**
* Features context.
*/
class DrupalContext extends MinkContext implements DrupalAwareInterface {
private $drupal, $drupalParameters;
/**
* Basic auth user and password.
*/
public $basic_auth;
...
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: installation
# composer.json
{
"require": {
"drupal/drupal-extension": "*"
},
"minimum-stability": "dev",
"config": {
"bin-dir": "bin/"
}
}
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: installtion
$ curl http://getcomposer.org/installer | php
$ php composer.phar install
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: configuration
#behat.yml
default:
paths:
features: 'features'
extensions:
BehatMinkExtensionExtension:
goutte: ~
selenium2: ~
base_url: http://www.campusfrance.org/
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: configuration
#behat.yml
default:
paths:
features: 'features'
extensions:
BehatMinkExtensionExtension:
goutte: ~
selenium2: ~
base_url: http://www.campusfrance.org/
DrupalDrupalExtensionExtension:
blackbox: ~
https://drupal.org/project/drupalextension
Développement
● Drupal Extension en pratique
bin/behat -dl => liste les steps
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: user steps
Given /^I am an anonymous user$/
Given /^I am not logged in$/
Given /^I am logged in as a user with the "(?P<role>[^"]*)" role$/
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: configuration
#behat.yml
default:
paths:
features: 'features'
extensions:
...
DrupalDrupalExtensionExtension:
blackbox: ~
drush:
alias: myDrushAlias
https://drupal.org/project/drupalextension
Opened blackbox
● Drupal Extension: user steps
# @see Drupal/DrupalExtension/Context/DrupalContext.php
/**
* Helper function to login the current user.
*/
public function login() {
...
$this->getSession()->visit($this->locatePath('/user'));
$element = $this->getSession()->getPage();
$element->fillField($this->getDrupalText('username_field'), $this->user->name);
$element->fillField($this->getDrupalText('password_field'), $this->user->pass);
$submit = $element->findButton($this->getDrupalText('log_in'));
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: user steps
#behat.yml
DrupalDrupalExtensionExtension:
text:
log_out: "Sign out"
log_in: "Sign in"
password_field: "Enter your password"
username_field: "Nickname"
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: content steps
Given /^I am viewing (?:a|an) "(?P<type>[^"]*)" node with the title "(?P<title>[^"
Given /^I am viewing (?:a|an) "(?P<vocabulary>[^"]*)" term with the name "(?
P<name>[^"]*)"$/
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: region steps
Then /^I should see the "(?P<heading>[^"]*)" heading in the "(?P<region>[^"]*)"(?:|reg
When /^I (?:follow|click) "(?P<link>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/
Then /^I should see the link "(?P<link>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/
Given /^I press "(?P<button>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: region steps
#behat.yml
DrupalDrupalExtensionExtension:
region_map:
My region: "#css-selector"
Content: "#main .region-content"
Right sidebar: "#sidebar-second"
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: misc steps
Given /^the cache has been cleared$/
Given /^I run cron$/
https://drupal.org/project/drupalextension
Développement
Démo
Développement
Conclusion:
Utilisez BDD pour faire des tests de régressions.
Introduction aux tests de recette automatisés
Avec l'extension Drupal pour Behat
didier.boff@ows.fr
B2F @ drupal.org
https://github.com/B2F
http:///twitter.com/zenelse
Merci de votre attention

More Related Content

Similar to Drupal camp paris 2013: présentation de Behat, Mink et Drupal extension

Favorite Sites And iOS Applications Of Productive Camp Directors
Favorite Sites And iOS Applications Of Productive Camp DirectorsFavorite Sites And iOS Applications Of Productive Camp Directors
Favorite Sites And iOS Applications Of Productive Camp DirectorsJennifer Selke
 
Phpday - Automated acceptance testing with Behat and Mink
Phpday - Automated acceptance testing with Behat and MinkPhpday - Automated acceptance testing with Behat and Mink
Phpday - Automated acceptance testing with Behat and MinkRichard Tuin
 
Webinar - PuppetDB
Webinar - PuppetDBWebinar - PuppetDB
Webinar - PuppetDBOlinData
 
How to not blow up spaceships
How to not blow up spaceshipsHow to not blow up spaceships
How to not blow up spaceshipsSabin Marcu
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScriptT11 Sessions
 
Zero to hero - Geoff Webb
Zero to hero - Geoff WebbZero to hero - Geoff Webb
Zero to hero - Geoff WebbDevopsdays
 
Översättning av django-program
Översättning av django-programÖversättning av django-program
Översättning av django-programmikaelmoutakis
 
DrupalCon Paris Muiltilingual Panel
DrupalCon Paris Muiltilingual PanelDrupalCon Paris Muiltilingual Panel
DrupalCon Paris Muiltilingual PanelDoug Green
 
Practical Accessibility
Practical AccessibilityPractical Accessibility
Practical AccessibilityEli Cochran
 
Introduction to Continous Integration with WordPress
Introduction to Continous Integration with WordPressIntroduction to Continous Integration with WordPress
Introduction to Continous Integration with WordPressSeagyn Davis
 
Electronic Grading of Paper Assessments
Electronic Grading of Paper AssessmentsElectronic Grading of Paper Assessments
Electronic Grading of Paper AssessmentsMatthew Leingang
 
JLPDevs - Optimization Tooling for Modern Web App Development
JLPDevs - Optimization Tooling for Modern Web App DevelopmentJLPDevs - Optimization Tooling for Modern Web App Development
JLPDevs - Optimization Tooling for Modern Web App DevelopmentJLP Community
 
Groovy And Grails Introduction
Groovy And Grails IntroductionGroovy And Grails Introduction
Groovy And Grails IntroductionEric Weimer
 
BDD / cucumber /Capybara
BDD / cucumber /CapybaraBDD / cucumber /Capybara
BDD / cucumber /CapybaraShraddhaSF
 
Drupal site translation and translation testing
Drupal site translation and translation testingDrupal site translation and translation testing
Drupal site translation and translation testingjames_andres
 

Similar to Drupal camp paris 2013: présentation de Behat, Mink et Drupal extension (20)

Favorite Sites And iOS Applications Of Productive Camp Directors
Favorite Sites And iOS Applications Of Productive Camp DirectorsFavorite Sites And iOS Applications Of Productive Camp Directors
Favorite Sites And iOS Applications Of Productive Camp Directors
 
Phpday - Automated acceptance testing with Behat and Mink
Phpday - Automated acceptance testing with Behat and MinkPhpday - Automated acceptance testing with Behat and Mink
Phpday - Automated acceptance testing with Behat and Mink
 
Webinar - PuppetDB
Webinar - PuppetDBWebinar - PuppetDB
Webinar - PuppetDB
 
How to not blow up spaceships
How to not blow up spaceshipsHow to not blow up spaceships
How to not blow up spaceships
 
Devops
DevopsDevops
Devops
 
Code Management
Code ManagementCode Management
Code Management
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScript
 
Zero to hero - Geoff Webb
Zero to hero - Geoff WebbZero to hero - Geoff Webb
Zero to hero - Geoff Webb
 
Översättning av django-program
Översättning av django-programÖversättning av django-program
Översättning av django-program
 
DrupalCon Paris Muiltilingual Panel
DrupalCon Paris Muiltilingual PanelDrupalCon Paris Muiltilingual Panel
DrupalCon Paris Muiltilingual Panel
 
Practical Accessibility
Practical AccessibilityPractical Accessibility
Practical Accessibility
 
2013 10-25 dev-opsdays
2013 10-25 dev-opsdays2013 10-25 dev-opsdays
2013 10-25 dev-opsdays
 
13 Ddply
13 Ddply13 Ddply
13 Ddply
 
Introduction to Continous Integration with WordPress
Introduction to Continous Integration with WordPressIntroduction to Continous Integration with WordPress
Introduction to Continous Integration with WordPress
 
Electronic Grading of Paper Assessments
Electronic Grading of Paper AssessmentsElectronic Grading of Paper Assessments
Electronic Grading of Paper Assessments
 
JLPDevs - Optimization Tooling for Modern Web App Development
JLPDevs - Optimization Tooling for Modern Web App DevelopmentJLPDevs - Optimization Tooling for Modern Web App Development
JLPDevs - Optimization Tooling for Modern Web App Development
 
Introduction to Jifty
Introduction to JiftyIntroduction to Jifty
Introduction to Jifty
 
Groovy And Grails Introduction
Groovy And Grails IntroductionGroovy And Grails Introduction
Groovy And Grails Introduction
 
BDD / cucumber /Capybara
BDD / cucumber /CapybaraBDD / cucumber /Capybara
BDD / cucumber /Capybara
 
Drupal site translation and translation testing
Drupal site translation and translation testingDrupal site translation and translation testing
Drupal site translation and translation testing
 

Recently uploaded

GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 

Recently uploaded (20)

GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 

Drupal camp paris 2013: présentation de Behat, Mink et Drupal extension