diff --git a/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php b/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php
index fcfd62aed4ae34d3731f5874db338600816f7864..a402eaca7071171b4577f0e0e2af945cad1552bb 100644
--- a/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php
+++ b/core/modules/email/lib/Drupal/email/Tests/EmailItemTest.php
@@ -7,22 +7,21 @@
 
 namespace Drupal\email\Tests;
 
-use Drupal\simpletest\DrupalUnitTestBase;
-use Drupal\email\Type\EmailItem;
-use Drupal\Core\Entity\Field\FieldItemInterface;
 use Drupal\Core\Entity\Field\FieldInterface;
+use Drupal\Core\Entity\Field\FieldItemInterface;
+use Drupal\field\Tests\FieldItemUnitTestBase;
 
 /**
  * Tests the new entity API for the email field type.
  */
-class EmailItemTest extends DrupalUnitTestBase {
+class EmailItemTest extends FieldItemUnitTestBase {
 
   /**
    * Modules to enable.
    *
    * @var array
    */
-  public static $modules = array('email', 'entity_test');
+  public static $modules = array('email');
 
   public static function getInfo() {
     return array(
@@ -34,7 +33,6 @@ public static function getInfo() {
 
   public function setUp() {
     parent::setUp();
-    $this->enableModules(array('system', 'entity', 'field', 'text', 'options', 'field_sql_storage', 'entity_test', 'email'));
 
     // Create an email field and instance for validation.
     $this->field = array(
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldItemUnitTestBase.php b/core/modules/field/lib/Drupal/field/Tests/FieldItemUnitTestBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..e201fb57f84b3fe6f4bcfdaa3a1fc938d2a5b377
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldItemUnitTestBase.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Tests\FieldItemUnitTestBase.
+ */
+
+namespace Drupal\field\Tests;
+
+use Drupal\simpletest\DrupalUnitTestBase;
+
+/**
+ * Base test class for field type item tests.
+ */
+class FieldItemUnitTestBase extends DrupalUnitTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('user', 'system', 'field', 'text', 'field_sql_storage', 'field_test', 'entity_test');
+
+  public function setUp() {
+    parent::setUp();
+    $this->installSchema('system', 'sequences');
+    $this->installSchema('field', 'field_config');
+    $this->installSchema('field', 'field_config_instance');
+    $this->installSchema('entity_test', 'entity_test');
+  }
+
+}
diff --git a/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php b/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5e52c1b7e070f3fe78217a00e39a0e342b41d77
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Tests/ShapeItemTest.php
@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Tests\ShapeItemTest.
+ */
+
+namespace Drupal\field\Tests;
+
+use Drupal\Core\Entity\Field\FieldItemInterface;
+use Drupal\Core\Entity\Field\FieldInterface;
+
+/**
+ * Tests the new entity API for the shape field type.
+ */
+class ShapeItemTest extends FieldItemUnitTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('field_test');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Shape field item',
+      'description' => 'Tests the new entity API for the shape field type.',
+      'group' => 'Field types',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+
+    // Create an field field and instance for validation.
+    $this->field = array(
+      'field_name' => 'field_shape',
+      'type' => 'shape',
+    );
+    field_create_field($this->field);
+    $this->instance = array(
+      'entity_type' => 'entity_test',
+      'field_name' => 'field_shape',
+      'bundle' => 'entity_test',
+      'widget' => array(
+        'type' => 'test_field_widget',
+      ),
+    );
+    field_create_instance($this->instance);
+  }
+
+  /**
+   * Tests using entity fields of the field field type.
+   */
+  public function testShapeItem() {
+    // Verify entity creation.
+    $entity = entity_create('entity_test', array());
+    $shape = 'cube';
+    $color = 'blue';
+    $entity->field_shape->shape = $shape;
+    $entity->field_shape->color = $color;
+    $entity->name->value = $this->randomName();
+    $entity->save();
+
+    // Verify entity has been created properly.
+    $id = $entity->id();
+    $entity = entity_load('entity_test', $id);
+    $this->assertTrue($entity->field_shape instanceof FieldInterface, 'Field implements interface.');
+    $this->assertTrue($entity->field_shape[0] instanceof FieldItemInterface, 'Field item implements interface.');
+    $this->assertEqual($entity->field_shape->shape, $shape);
+    $this->assertEqual($entity->field_shape->color, $color);
+    $this->assertEqual($entity->field_shape[0]->shape, $shape);
+    $this->assertEqual($entity->field_shape[0]->color, $color);
+
+    // Verify changing the field value.
+    $new_shape = 'circle';
+    $new_color = 'red';
+    $entity->field_shape->shape = $new_shape;
+    $entity->field_shape->color = $new_color;
+    $this->assertEqual($entity->field_shape->shape, $new_shape);
+    $this->assertEqual($entity->field_shape->color, $new_color);
+
+    // Read changed entity and assert changed values.
+    $entity->save();
+    $entity = entity_load('entity_test', $id);
+    $this->assertEqual($entity->field_shape->shape, $new_shape);
+    $this->assertEqual($entity->field_shape->color, $new_color);
+  }
+
+}
diff --git a/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php b/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a1cce1668c4a75696bda6c7adc3ee4462c0810e8
--- /dev/null
+++ b/core/modules/field/lib/Drupal/field/Tests/TestItemTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field\Tests\TestItemTest.
+ */
+
+namespace Drupal\field\Tests;
+
+use Drupal\Core\Entity\Field\FieldItemInterface;
+use Drupal\Core\Entity\Field\FieldInterface;
+
+/**
+ * Tests the new entity API for the test field type.
+ */
+class TestItemTest extends FieldItemUnitTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('field_test');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Test field item',
+      'description' => 'Tests the new entity API for the test field type.',
+      'group' => 'Field types',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+
+    // Create an field field and instance for validation.
+    $this->field = array(
+      'field_name' => 'field_test',
+      'type' => 'test_field',
+    );
+    field_create_field($this->field);
+    $this->instance = array(
+      'entity_type' => 'entity_test',
+      'field_name' => 'field_test',
+      'bundle' => 'entity_test',
+      'widget' => array(
+        'type' => 'test_field_widget',
+      ),
+    );
+    field_create_instance($this->instance);
+  }
+
+  /**
+   * Tests using entity fields of the field field type.
+   */
+  public function testTestItem() {
+    // Verify entity creation.
+    $entity = entity_create('entity_test', array());
+    $value = $this->randomName();
+    $entity->field_test = $value;
+    $entity->name->value = $this->randomName();
+    $entity->save();
+
+    // Verify entity has been created properly.
+    $id = $entity->id();
+    $entity = entity_load('entity_test', $id);
+    $this->assertTrue($entity->field_test instanceof FieldInterface, 'Field implements interface.');
+    $this->assertTrue($entity->field_test[0] instanceof FieldItemInterface, 'Field item implements interface.');
+    $this->assertEqual($entity->field_test->value, $value);
+    $this->assertEqual($entity->field_test[0]->value, $value);
+
+    // Verify changing the field value.
+    $new_value = $this->randomName();
+    $entity->field_test->value = $new_value;
+    $this->assertEqual($entity->field_test->value, $new_value);
+
+    // Read changed entity and assert changed values.
+    $entity->save();
+    $entity = entity_load('entity_test', $id);
+    $this->assertEqual($entity->field_test->value, $new_value);
+  }
+
+}
diff --git a/core/modules/field/tests/modules/field_test/field_test.entity.inc b/core/modules/field/tests/modules/field_test/field_test.entity.inc
index 1f8bd4b44f8eab4a13cc04afbb4c407dfaf6d1e8..11620f98163210318d8e94a0b0dfa5313d5e7908 100644
--- a/core/modules/field/tests/modules/field_test/field_test.entity.inc
+++ b/core/modules/field/tests/modules/field_test/field_test.entity.inc
@@ -172,6 +172,10 @@ function field_test_create_entity($id = 1, $vid = 1, $bundle = 'test_bundle', $l
  *   The loaded entity.
  */
 function field_test_entity_test_load($ftid, $ftvid = NULL) {
+  // Prevent this from being called as hook_entity_test_load().
+  if (is_array($ftid)) {
+    return;
+  }
   $ids = (isset($ftid) ? array($ftid) : array());
   $conditions = (isset($ftvid) ? array('ftvid' => $ftvid) : array());
   $test_entity = entity_load_multiple('test_entity', $ids, $conditions);
diff --git a/core/modules/field/tests/modules/field_test/field_test.field.inc b/core/modules/field/tests/modules/field_test/field_test.field.inc
index a5f6fa5c9f02c4b97d2fdaa5071047d7fd7f628f..7166f4b14c5e255f21920a08e592b866b66473fc 100644
--- a/core/modules/field/tests/modules/field_test/field_test.field.inc
+++ b/core/modules/field/tests/modules/field_test/field_test.field.inc
@@ -27,6 +27,7 @@ function field_test_field_info() {
       ),
       'default_widget' => 'test_field_widget',
       'default_formatter' => 'field_test_default',
+      'field item class' => 'Drupal\field_test\Type\TestItem',
     ),
     'shape' => array(
       'label' => t('Shape'),
@@ -35,6 +36,7 @@ function field_test_field_info() {
       'instance_settings' => array(),
       'default_widget' => 'test_field_widget',
       'default_formatter' => 'field_test_default',
+      'field item class' => 'Drupal\field_test\Type\ShapeItem',
     ),
     'hidden_test_field' => array(
       'no_ui' => TRUE,
@@ -44,6 +46,7 @@ function field_test_field_info() {
       'instance_settings' => array(),
       'default_widget' => 'test_field_widget',
       'default_formatter' => 'field_test_default',
+      'field item class' => 'Drupal\field_test\Type\TestItem',
     ),
   );
 }
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Type/ShapeItem.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Type/ShapeItem.php
new file mode 100644
index 0000000000000000000000000000000000000000..1a67329a5f9c43ed544ecb3610453abf319d464a
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Type/ShapeItem.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field_test\Type\ShapeItem.
+ */
+
+namespace Drupal\field_test\Type;
+
+use Drupal\Core\Entity\Field\FieldItemBase;
+
+/**
+ * Defines the 'shape_field' entity field item.
+ */
+class ShapeItem extends FieldItemBase {
+
+  /**
+   * Property definitions of the contained properties.
+   *
+   * @see ShapeItem::getPropertyDefinitions()
+   *
+   * @var array
+   */
+  static $propertyDefinitions;
+
+  /**
+   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
+   */
+  public function getPropertyDefinitions() {
+
+    if (!isset(static::$propertyDefinitions)) {
+      static::$propertyDefinitions['shape'] = array(
+        'type' => 'string',
+        'label' => t('Shape'),
+      );
+      static::$propertyDefinitions['color'] = array(
+        'type' => 'string',
+        'label' => t('Color'),
+      );
+    }
+    return static::$propertyDefinitions;
+  }
+
+}
diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Type/TestItem.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Type/TestItem.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c61d1529708be3a31cd45e0d1d29824f739d670
--- /dev/null
+++ b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Type/TestItem.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\field_test\Type\TestItem.
+ */
+
+namespace Drupal\field_test\Type;
+
+use Drupal\Core\Entity\Field\FieldItemBase;
+
+/**
+ * Defines the 'test_field' entity field item.
+ */
+class TestItem extends FieldItemBase {
+
+  /**
+   * Property definitions of the contained properties.
+   *
+   * @see TestItem::getPropertyDefinitions()
+   *
+   * @var array
+   */
+  static $propertyDefinitions;
+
+  /**
+   * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions().
+   */
+  public function getPropertyDefinitions() {
+
+    if (!isset(static::$propertyDefinitions)) {
+      static::$propertyDefinitions['value'] = array(
+        'type' => 'integer',
+        'label' => t('Test integer value'),
+      );
+    }
+    return static::$propertyDefinitions;
+  }
+
+}
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php
index 99258bc12c03b96baceaef9c701214c75358d224..f4b0ec8121d55764fd774629fc790bd9394a763a 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php
@@ -7,26 +7,25 @@
 
 namespace Drupal\taxonomy\Tests;
 
-use Drupal\simpletest\WebTestBase;
-use Drupal\taxonomy\Type\TaxonomyTermReferenceItem;
-use Drupal\Core\Entity\Field\FieldItemInterface;
 use Drupal\Core\Entity\Field\FieldInterface;
+use Drupal\Core\Entity\Field\FieldItemInterface;
+use Drupal\field\Tests\FieldItemUnitTestBase;
 
 /**
  * Tests the new entity API for the taxonomy term reference field type.
  */
-class TaxonomyTermReferenceItemTest extends WebTestBase {
+class TaxonomyTermReferenceItemTest extends FieldItemUnitTestBase {
 
   /**
    * Modules to enable.
    *
    * @var array
    */
-  public static $modules = array('field', 'field_sql_storage', 'taxonomy', 'entity_test', 'options');
+  public static $modules = array('taxonomy', 'options');
 
   public static function getInfo() {
     return array(
-      'name' => 'Taxonomy reference API',
+      'name' => 'Taxonomy reference field item',
       'description' => 'Tests using entity fields of the taxonomy term reference field type.',
       'group' => 'Taxonomy',
     );
@@ -34,6 +33,9 @@ public static function getInfo() {
 
   public function setUp() {
     parent::setUp();
+    $this->installSchema('taxonomy', 'taxonomy_term_data');
+    $this->installSchema('taxonomy', 'taxonomy_term_hierarchy');
+
     $vocabulary = entity_create('taxonomy_vocabulary', array(
       'name' => $this->randomName(),
       'vid' => drupal_strtolower($this->randomName()),