diff --git tests/entity_translation.test tests/entity_translation.test
index c40b1e9..2e8e330 100644
--- tests/entity_translation.test
+++ tests/entity_translation.test
@@ -5,3 +5,596 @@
  * Tests for Entity Translation module.
  */
 
+
+/**
+ * Base class for entity translation module
+ *
+ * A lot of these methods base on the i18n base class for tests.
+ */
+class EntityTranslationTestCase extends DrupalWebTestCase {
+
+  /**
+   * Stores the current user to avoid logging in twice.
+   */
+  protected $current_user;
+
+  /**
+   * Retrieves a Drupal path or an absolute path with language
+   *
+   * @param $language
+   *   Language code or language object
+   */
+  function etGet($language, $path = '', array $options = array(), array $headers = array()) {
+    $options['language'] = $this->getLanguage($language);
+    return $this->drupalGet($path, $options, $headers);
+  }
+
+  /**
+   * Login user, only if changed
+   */
+  function etLogin($user) {
+    if (!isset($this->current_user) || $this->current_user->uid != $user->uid) {
+      $this->current_user = $user;
+      $this->drupalLogin($user);
+    }
+  }
+
+  /**
+   * Check strings for different languages
+   */
+  function etAssertTranslations($translations, $path = '', $message = 'Translation found for language.') {
+    foreach ($translations as $langcode => $text) {
+      $language = $this->getLanguage($langcode);
+      if ($language->enabled) {
+        $this->i18nGet($language, $path);
+        $this->assertRaw($text, $message . ' ' . $language->name . ': ' . check_plain($text));
+      }
+    }
+  }
+
+  /**
+   * Returns an user with administration rights
+   */
+  function getAdminUser() {
+    if (!isset($this->admin_user)) {
+      $this->admin_user = $this->drupalCreateUser(array(
+        'bypass node access',
+        'administer nodes',
+        'administer languages',
+        'administer content types',
+        'administer blocks',
+        'access administration pages',
+        'administer site configuration',
+      ));
+    }
+    return $this->admin_user;
+  }
+
+  /**
+   * Returns an user with minimal translation rights.
+   */
+  function getTranslatorUser() {
+    if (!isset($this->translator_user)) {
+      $this->translator_user = $this->drupalCreateUser(array(
+        'create page content',
+        'edit own page content',
+        'translate content',
+        'translate any entity',
+      ));
+    }
+    return $this->translator_user;
+  }
+
+  /**
+   * Make sure the clean urls are enabled.
+   */
+  function enableCleanUrls() {
+    $this->drupalGet('admin/config/search/clean-urls');
+    $edit = array();
+    $edit['clean_url'] = TRUE;
+    $this->drupalPost(NULL, $edit, t('Save configuration'));
+  }
+
+  /**
+   * Get language object for langcode
+   */
+  public function getLanguage($langcode) {
+    if (is_object($langcode)) {
+      return $langcode;
+    }
+    else {
+      $language_list = language_list();
+      return $language_list[$langcode];
+    }
+  }
+
+  /**
+   * Install a specified language if it has not been already.
+   *
+   * Otherwise make sure that the language is enabled.
+   *
+   * @param $language_code
+   *   The language code to check.
+   */
+  function addLanguage($language_code) {
+    // Check to make sure that language has not already been installed.
+    $this->drupalGet('admin/config/regional/language');
+
+    if (strpos($this->drupalGetContent(), 'enabled[' . $language_code . ']') === FALSE) {
+      // Doesn't have language installed so add it.
+      $edit = array();
+      $edit['langcode'] = $language_code;
+      $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
+
+      // Make sure we're not using a stale list.
+      drupal_static_reset('language_list');
+      $languages = language_list('language');
+      $this->assertTrue(array_key_exists($language_code, $languages), t('Language was installed successfully.'));
+
+      if (array_key_exists($language_code, $languages)) {
+        $this->assertRaw(t('The language %language has been created and can now be used. More information is available on the <a href="@locale-help">help screen</a>.', array('%language' => $languages[$language_code]->name, '@locale-help' => url('admin/help/locale'))), t('Language has been created.'));
+      }
+    }
+    elseif ($this->xpath('//input[@type="checkbox" and @name=:name and @checked="checked"]', array(':name' => 'enabled[' . $language_code . ']'))) {
+      // It's installed and enabled. No need to do anything.
+      $this->assertTrue(TRUE, 'Language [' . $language_code . '] already installed and enabled.');
+    }
+    else {
+      // It's installed but not enabled. Enable it.
+      $this->assertTrue(TRUE, 'Language [' . $language_code . '] already installed.');
+      $this->drupalPost(NULL, array('enabled[' . $language_code . ']' => TRUE), t('Save configuration'));
+      $this->assertRaw(t('Configuration saved.'), t('Language successfully enabled.'));
+    }
+  }
+
+  /**
+   * Configure the content type for this test.
+   *
+   * Enable content translation.
+   * Change body to multivalue field.
+   */
+  function configureContentType() {
+    // Configure "Basic page" content type to use multilingual support with
+    // translation.
+    $this->drupalGet('admin/structure/types/manage/page');
+    $edit = array();
+    $edit['language_content_type'] = 4;
+    $this->drupalPost('admin/structure/types/manage/page', $edit, t('Save content type'));
+    $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Basic page')), t('Basic page content type has been updated.'));
+
+    // Set body field to multivalue
+    $this->drupalGet('admin/structure/types/manage/page/fields/body');
+    $edit = array();
+    $edit['field[cardinality]'] = -1; // Unlimited
+    $this->drupalPost('admin/structure/types/manage/page/fields/body', $edit, t('Save settings'));
+    $this->assertRaw(t('Saved %field configuration.', array('%field' => 'Body')), t('Body field settings have been updated.'));
+
+    // Check if the multivalue setting works
+    $this->drupalGet('node/add/page');
+    $this->assertFieldById('edit-body-und-add-more', t('Add another item'), t('Add another item button found.'));
+  }
+
+  /**
+   * Create a "Basic page" in the specified language.
+   *
+   * @param $title
+   *   Title of basic page in specified language.
+   * @param $body
+   *   Body of basic page in specified language.
+   * @param $language
+   *   Language code.
+   */
+  function createPage($title, $body, $language) {
+    $edit = array();
+    $langcode = LANGUAGE_NONE;
+    $edit["title"] = $title;
+    $edit["body[$langcode][0][value]"] = $body;
+    $edit['language'] = $language;
+    $this->drupalPost('node/add/page', $edit, t('Save'));
+    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), t('Basic page created.'));
+
+    // Check to make sure the node was created.
+    $node = $this->drupalGetNodeByTitle($title);
+    $this->assertTrue($node, t('Node found in database.'));
+
+    return $node;
+  }
+
+  /**
+   * Create a translation.
+   *
+   * @param $node
+   *   Node of the basic page to create translation for.
+   * @param $title
+   *   Title of basic page in specified language.
+   * @param $body
+   *   Body of basic page in specified language.
+   * @param $language
+   *   Language code.
+   */
+  function createTranslation($node, $title, $body, $language) {
+    $this->drupalGet('node/' . $node->nid . '/translate/add/es/en');
+
+    $body_key = "body[$language][0][value]";
+    $this->assertFieldByXPath(
+      "//textarea[@name='$body_key']",
+      $node->body[$node->language][0]['value'],
+      'Original body value correctly populated.'
+    );
+
+    $this->assertFieldById(
+      'edit-body-' . $language . '-add-more',
+      t('Add another item'),
+      t('Add another item button found.')
+    );
+
+    $edit = array();
+    $edit[$body_key] = $body;
+
+    // Since there's no path stuff enabled make sure we don't see these options.
+    $this->assertNoFieldById('edit-path', NULL, 'Url-Alias fieldset hidden.');
+    $this->assertNoFieldById('edit-path-alias', NULL, 'Path alias field hidden.');
+    $this->assertNoFieldById('edit-path-pathauto', NULL, 'Pathauto checkbox hidden.');
+
+    $this->drupalPost(NULL, $edit, t('Save translation'));
+    $this->assertLinkByHref(
+      'node/' . $node->nid . '/translate/edit/' . $language,
+      0,
+      t('Translation edit link found. Translation created.')
+    );
+
+    return $node;
+  }
+}
+
+class EntityTranslationTranslationTestCase extends EntityTranslationTestCase {
+  /**
+   * Return the test information.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity translation workflow',
+      'description' => 'Create a basic page with translation and multivalue field.',
+      'group' => 'Entity translation',
+    );
+  }
+
+  /**
+   * Prepare basic test environment.
+   *
+   * Enable modules depending on.
+   */
+  function setUp() {
+    parent::setUp('locale', 'translation', 'entity_translation');
+  }
+
+
+  /**
+   * Test if field based translation works.
+   *
+   * Enable field based translation for basic pages.
+   * Add a field with a cardinality higher than 1, to test if
+   * field_default_extract_form_values() is invoked.
+   * Create basic page.
+   * Translate basic page.
+   */
+  function testFieldTranslation() {
+    $this->etLogin($this->getAdminUser());
+
+    // Add languages.
+    $this->addLanguage('en');
+    $this->addLanguage('es');
+
+    // Configure Content Type
+    $this->configureContentType();
+
+    // Make sure we run with the minimal rights.
+    $this->etLogin($this->getTranslatorUser());
+
+    // Create Basic page in English.
+    $node_title = $this->randomName();
+    $node_body = $this->randomName();
+    $node = $this->createPage($node_title, $node_body, 'en');
+
+    // Submit translation in Spanish.
+    $node_translation_title = $this->randomName();
+    $node_translation_body = $this->randomName();
+    $node_translation = $this->createTranslation($node, $node_translation_title, $node_translation_body, 'es');
+  }
+
+
+}
+
+/**
+ * Tests the path aliases handling of nodes when translating.
+ */
+class EntityTranslationPathAliasesTestCase extends EntityTranslationTestCase {
+
+  /**
+   * Return the test information.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity translation path aliases support',
+      'description' => 'Create a basic page with translation and path aliases.',
+      'group' => 'Entity translation',
+    );
+  }
+
+  /**
+   * Prepare basic test environment.
+   *
+   * Enable modules depending on.
+   */
+  function setUp() {
+    parent::setUp('path', 'locale', 'translation', 'entity_translation');
+  }
+
+  /**
+   * Returns an user with minimal translation rights.
+   */
+  function getTranslatorUser() {
+    if (!isset($this->translator_user)) {
+      $this->translator_user = $this->drupalCreateUser(array(
+        'create page content',
+        'edit own page content',
+        'translate content',
+        'translate any entity',
+        'create url aliases',
+      ));
+    }
+    return $this->translator_user;
+  }
+
+  /**
+   * Test if the aliases work with the field translation.
+   *
+   * Enable field based translation for basic pages.
+   * Add a field with a cardinality higher than 1, to test if
+   * field_default_extract_form_values() is invoked.
+   * Create basic page.
+   * Translate basic page.
+   */
+  function testAliasesOnFieldTranslation() {
+    $this->etLogin($this->getAdminUser());
+
+    // Add languages.
+    $this->addLanguage('en');
+    $this->addLanguage('es');
+
+    $this->enableCleanUrls();
+
+    // Configure Content Type
+    $this->configureContentType();
+
+    // Make sure we run with the minimal rights.
+    $this->etLogin($this->getTranslatorUser());
+
+    // Create Basic page in English.
+    $node_title = $this->randomName();
+    $node_body = $this->randomName();
+    $node = $this->createPage($node_title, $node_body, 'en');
+
+    // Submit translation in Spanish.
+    $node_translation_title = $this->randomName();
+    $node_translation_body = $this->randomName();
+    $node_translation = $this->createTranslation($node, $node_translation_title, $node_translation_body, 'es');
+  }
+
+  /**
+   * Create a translation.
+   *
+   * @param $node
+   *   Node of the basic page to create translation for.
+   * @param $title
+   *   Title of basic page in specified language.
+   * @param $body
+   *   Body of basic page in specified language.
+   * @param $language
+   *   Language code.
+   */
+  function createTranslation($node, $title, $body, $language) {
+    $this->drupalGet('node/' . $node->nid . '/translate/add/es/en');
+
+    $body_key = "body[$language][0][value]";
+    $this->assertFieldByXPath(
+      "//textarea[@name='$body_key']",
+      $node->body[$node->language][0]['value'],
+      'Original body value correctly populated.'
+    );
+
+    $this->assertFieldById(
+      'edit-body-' . $language . '-add-more',
+      t('Add another item'),
+      t('Add another item button found.')
+    );
+
+    $edit = array();
+    $edit[$body_key] = $body;
+
+    $this->assertFieldById('edit-path-alias', NULL, 'Path alias field found.');
+    $edit['path[alias]'] = 'i-wish-i-had-a-pink-unicorn';
+
+    $this->drupalPost(NULL, $edit, t('Save translation'));
+    $this->assertLinkByHref(
+      'node/' . $node->nid . '/translate/edit/' . $language,
+      0,
+      t('Translation edit link found. Translation created.')
+    );
+
+    $this->drupalGet('node/' . $node->nid . '/translate/edit/' . $language);
+    $this->assertFieldById('edit-path-alias', 'i-wish-i-had-a-pink-unicorn', 'Path alias stored.');
+
+    // @TODO I'd like to test if the path is reachable but I can't get this
+    // working atm.
+    // $this->etGet($language, 'i-wish-i-had-a-pink-unicorn');
+
+    return $node;
+  }
+}
+
+
+/**
+* Tests the path aliases handling of nodes when translating.
+*/
+class EntityTranslationPathautoTestCase extends EntityTranslationTestCase {
+
+  /**
+   * Return the test information.
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Entity translation pathauto support',
+      'description' => 'Create a basic page with translation and enabled pathauto.',
+      'group' => 'Entity translation',
+    );
+  }
+
+  /**
+   * Prepare basic test environment.
+   *
+   * Enable modules depending on.
+   * Depends on the title module since this takes care of translating tokens.
+   */
+  function setUp() {
+    parent::setUp('title', 'pathauto', 'token', 'path', 'locale', 'translation', 'entity_translation');
+  }
+
+  /**
+   * Returns an user with minimal translation rights.
+   */
+  function getTranslatorUser() {
+    if (!isset($this->translator_user)) {
+      $this->translator_user = $this->drupalCreateUser(array(
+        'create page content',
+        'edit own page content',
+        'translate content',
+        'translate any entity',
+        'create url aliases',
+      ));
+    }
+    return $this->translator_user;
+  }
+
+  /**
+   * Test if the aliases work with the field translation.
+   *
+   * Enable field based translation for basic pages.
+   * Add a field with a cardinality higher than 1, to test if
+   * field_default_extract_form_values() is invoked.
+   * Create basic page.
+   * Translate basic page.
+   */
+  function testPathautoOnFieldTranslation() {
+    $this->etLogin($this->getAdminUser());
+
+    // Add languages.
+    $this->addLanguage('en');
+    $this->addLanguage('es');
+
+    $this->enableCleanUrls();
+
+    // Configure Content Type
+    $this->configureContentType();
+    $this->enablePageTitleTranslation();
+
+    // Make sure we run with the minimal rights.
+    $this->etLogin($this->getTranslatorUser());
+
+    // Create Basic page in English.
+    $node_title = $this->randomName();
+    $node_body = $this->randomName();
+    $node = $this->createPage($node_title, $node_body, 'en');
+
+    // Submit translation in Spanish.
+    $node_translation_title = $this->randomName();
+    $node_translation_body = $this->randomName();
+    $node_translation = $this->createTranslation($node, $node_translation_title, $node_translation_body, 'es');
+  }
+
+  /**
+   * Enable page title translation.
+   */
+  function enablePageTitleTranslation() {
+    // Replace the title property by a translatable field
+    $this->drupalGet('admin/structure/types/manage/page/fields/replace/title');
+    $edit = array();
+    $edit['enabled'] = TRUE;
+    $this->drupalPost(NULL, $edit, t('Save settings'));
+  }
+
+  /**
+   * Create a "Basic page" in the specified language.
+   *
+   * @param $title
+   *   Title of basic page in specified language.
+   * @param $body
+   *   Body of basic page in specified language.
+   * @param $language
+   *   Language code.
+   */
+  function createPage($title, $body, $language) {
+    $edit = array();
+    $langcode = LANGUAGE_NONE;
+    $edit["title_field[$langcode][0][value]"] = $title;
+    $edit["body[$langcode][0][value]"] = $body;
+    $edit['language'] = $language;
+    $this->drupalPost('node/add/page', $edit, t('Save'));
+    $this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), t('Basic page created.'));
+
+    // Check to make sure the node was created.
+    $node = $this->drupalGetNodeByTitle($title);
+    $this->assertTrue($node, t('Node found in database.'));
+
+    return $node;
+  }
+
+  /**
+   * Create a translation.
+   *
+   * @param $node
+   *   Node of the basic page to create translation for.
+   * @param $title
+   *   Title of basic page in specified language.
+   * @param $body
+   *   Body of basic page in specified language.
+   * @param $language
+   *   Language code.
+   */
+  function createTranslation($node, $title, $body, $language) {
+    $this->drupalGet('node/' . $node->nid . '/translate/add/' . $language . '/en');
+
+    $body_key = "body[$language][0][value]";
+    $title_key = "title_field[$language][0][value]";
+    $this->assertFieldByXPath(
+      "//textarea[@name='$body_key']",
+      $node->body[$node->language][0]['value'],
+      'Original body value correctly populated.'
+    );
+    $this->assertFieldByXPath(
+      "//input[@name='$title_key']",
+      $node->title_field[$node->language][0]['value'],
+      'Original title value correctly populated.'
+    );
+
+    $this->assertFieldById('edit-path-pathauto', NULL, 'Pathauto checkbox found.');
+
+    // Set translation and alias settings.
+    $edit = array();
+    $edit[$body_key] = $body;
+    $edit[$title_key] = $title;
+    $edit['path[pathauto]'] = TRUE;
+    $this->drupalPost(NULL, $edit, t('Save translation'));
+    $this->assertLinkByHref(
+      'node/' . $node->nid . '/translate/edit/' . $language,
+      0,
+      t('Translation edit link found. Translation created.')
+    );
+
+    $this->drupalGet('node/' . $node->nid . '/translate/edit/' . $language);
+    $this->assertFieldById('edit-path-pathauto', TRUE, 'Pathauto checkbox is checked.');
+    $this->assertFieldById('edit-path-alias', 'content/' . strtolower($title), 'Autogenerated alias found.');
+
+    return $node;
+  }
+}
