diff --git a/graphene/contrib/django/fields.py b/graphene/contrib/django/fields.py
index a0d24555..ba47047e 100644
--- a/graphene/contrib/django/fields.py
+++ b/graphene/contrib/django/fields.py
@@ -66,6 +66,10 @@ class DjangoModelField(Field):
         resolved = super(DjangoModelField, self).resolve(instance, args, info)
         schema = info.schema.graphene_schema
         _type = self.get_object_type(schema)
+        assert _type, ("Field %s cannot be retrieved as the "
+                       "ObjectType is not registered by the schema" % (
+                           self.field_name
+                       ))
         return _type(resolved)
 
     @memoize
diff --git a/graphene/core/fields.py b/graphene/core/fields.py
index 6318c25a..d4c9f4a8 100644
--- a/graphene/core/fields.py
+++ b/graphene/core/fields.py
@@ -121,7 +121,7 @@ class Field(object):
         """
         Displays the module, class and name of the field.
         """
-        path = '%s[%s]' % (self.__class__.__name__, str(self.field_type))
+        path = '%s.%s' % (self.__class__.__module__, self.__class__.__name__)
         name = getattr(self, 'field_name', None)
         if name is not None:
             return '<%s: %s>' % (path, name)
diff --git a/graphene/core/types.py b/graphene/core/types.py
index fed216c4..e7b4e7fa 100644
--- a/graphene/core/types.py
+++ b/graphene/core/types.py
@@ -19,6 +19,9 @@ class ObjectTypeMeta(type):
     def is_interface(cls, parents):
         return Interface in parents
 
+    def is_mutation(cls, parents):
+        return Mutation in parents
+
     def __new__(cls, name, bases, attrs):
         super_new = super(ObjectTypeMeta, cls).__new__
         parents = [b for b in bases if isinstance(b, cls)]
@@ -44,6 +47,10 @@ class ObjectTypeMeta(type):
         new_class.add_to_class('_meta', new_class.options_cls(meta))
 
         new_class._meta.interface = new_class.is_interface(parents)
+        new_class._meta.mutation = new_class.is_mutation(parents)
+
+        assert not (new_class._meta.interface and new_class._meta.mutation)
+
         # Add all attributes to the class.
         for obj_name, obj in attrs.items():
             new_class.add_to_class(obj_name, obj)
@@ -155,5 +162,9 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
     pass
 
 
+class Mutation(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
+    pass
+
+
 class Interface(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
     pass
diff --git a/graphene/relay/types.py b/graphene/relay/types.py
index 50e43e9c..fce02aee 100644
--- a/graphene/relay/types.py
+++ b/graphene/relay/types.py
@@ -15,9 +15,9 @@ def get_node_type(schema, obj):
     return obj.internal_type(schema)
 
 
-def get_node(schema, globalId, *args):
-    resolvedGlobalId = from_global_id(globalId)
-    _type, _id = resolvedGlobalId.type, resolvedGlobalId.id
+def get_node(schema, global_id, *args):
+    resolved_global_id = from_global_id(global_id)
+    _type, _id = resolved_global_id.type, resolved_global_id.id
     object_type = schema.get_type(_type)
     if not object_type or not issubclass(object_type, BaseNode):
         raise Exception("The type %s is not a Node" % _type)
diff --git a/tests/contrib_django/test_urls.py b/tests/contrib_django/test_urls.py
index 6d0bca57..6b95105c 100644
--- a/tests/contrib_django/test_urls.py
+++ b/tests/contrib_django/test_urls.py
@@ -2,6 +2,7 @@ from django.conf.urls import url
 
 from graphene.contrib.django.views import GraphQLView
 
+import graphene
 from graphene import Schema
 from graphene.contrib.django.types import (
     DjangoNode,
@@ -20,9 +21,14 @@ class Character(DjangoNode):
 
 
 class Human(DjangoNode):
+    raises = graphene.StringField()
+
     class Meta:
         model = Article
 
+    def resolve_raises(self, *args):
+        raise Exception("This field should raise exception")
+
     def get_node(self, id):
         pass
 
diff --git a/tests/contrib_django/test_views.py b/tests/contrib_django/test_views.py
index be689062..435bcdf8 100644
--- a/tests/contrib_django/test_views.py
+++ b/tests/contrib_django/test_views.py
@@ -72,6 +72,14 @@ def test_client_get_good_query(settings, client):
     assert json_response == expected_json
 
 
+def test_client_get_good_query_with_raise(settings, client):
+    settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
+    response = client.get('/graphql', {'query': '{ raises }'})
+    json_response = format_response(response)
+    assert json_response['errors'][0]['message'] == 'This field should raise exception'
+    assert json_response['data']['raises'] is None
+
+
 def test_client_post_good_query(settings, client):
     settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
     response = client.post('/graphql', json.dumps({'query': '{ headline }'}), 'application/json')
diff --git a/tests/core/test_fields.py b/tests/core/test_fields.py
index 68497843..bb644306 100644
--- a/tests/core/test_fields.py
+++ b/tests/core/test_fields.py
@@ -4,6 +4,7 @@ from pytest import raises
 from graphene.core.fields import (
     Field,
     StringField,
+    NonNullField
 )
 
 from graphene.core.options import Options
@@ -27,6 +28,9 @@ class ObjectType(object):
     def can_resolve(self, *args):
         return True
 
+    def __str__(self):
+        return "ObjectType"
+
 ot = ObjectType()
 
 ObjectType._meta.contribute_to_class(ObjectType, '_meta')
@@ -69,6 +73,12 @@ def test_stringfield_type():
     assert f.internal_type(schema) == GraphQLString
 
 
+def test_nonnullfield_type():
+    f = NonNullField(StringField())
+    f.contribute_to_class(ot, 'field_name')
+    assert isinstance(f.internal_type(schema), GraphQLNonNull)
+
+
 def test_stringfield_type_required():
     f = StringField(required=True)
     f.contribute_to_class(ot, 'field_name')
@@ -108,3 +118,61 @@ def test_field_resolve_type_custom():
     f.contribute_to_class(ot, 'field_name')
     field_type = f.get_object_type(s)
     assert field_type == ot
+
+
+def test_field_orders():
+    f1 = Field(None)
+    f2 = Field(None)
+    assert f1 < f2
+
+
+def test_field_orders_wrong_type():
+    field = Field(None)
+    try:
+        assert not field < 1
+    except TypeError:
+        # Fix exception raising in Python3+
+        pass
+
+
+def test_field_eq():
+    f1 = Field(None)
+    f2 = Field(None)
+    assert f1 != f2
+
+
+def test_field_eq_wrong_type():
+    field = Field(None)
+    assert field != 1
+
+
+def test_field_hash():
+    f1 = Field(None)
+    f2 = Field(None)
+    assert hash(f1) != hash(f2)
+
+
+def test_field_none_type_raises_error():
+    s = Schema()
+    f = Field(None)
+    f.contribute_to_class(ot, 'field_name')
+    with raises(Exception) as excinfo:
+        f.internal_field(s)
+    assert str(excinfo.value) == "Internal type for field ObjectType.field_name is None"
+
+
+def test_field_str():
+    f = StringField()
+    f.contribute_to_class(ot, 'field_name')
+    assert str(f) == "ObjectType.field_name"
+
+
+def test_field_repr():
+    f = StringField()
+    assert repr(f) == "<graphene.core.fields.StringField>"
+
+
+def test_field_repr_contributed():
+    f = StringField()
+    f.contribute_to_class(ot, 'field_name')
+    assert repr(f) == "<graphene.core.fields.StringField: field_name>"
diff --git a/tests/core/test_scalars.py b/tests/core/test_scalars.py
new file mode 100644
index 00000000..654e99aa
--- /dev/null
+++ b/tests/core/test_scalars.py
@@ -0,0 +1,18 @@
+from graphene.core.scalars import (
+    GraphQLSkipField
+)
+
+
+def test_skipfield_serialize():
+    f = GraphQLSkipField
+    assert f.serialize('a') is None
+
+
+def test_skipfield_parse_value():
+    f = GraphQLSkipField
+    assert f.parse_value('a') is None
+
+
+def test_skipfield_parse_literal():
+    f = GraphQLSkipField
+    assert f.parse_literal('a') is None
diff --git a/tests/core/test_schema.py b/tests/core/test_schema.py
index 4d89d725..f6e3d849 100644
--- a/tests/core/test_schema.py
+++ b/tests/core/test_schema.py
@@ -109,3 +109,33 @@ def test_schema_get_type_map():
         schema.schema.get_type_map().keys(),
         ['__Field', 'String', 'Pet', 'Character', '__InputValue', '__Directive', '__TypeKind', '__Schema', '__Type', 'Human', '__EnumValue', 'Boolean']
     )
+
+
+def test_schema_no_query():
+    schema = Schema(name='My own schema')
+    with raises(Exception) as excinfo:
+        schema.schema
+    assert 'define a base query type' in str(excinfo)
+
+
+def test_schema_register():
+    schema = Schema(name='My own schema')
+
+    @schema.register
+    class MyType(ObjectType):
+        type = StringField(resolve=lambda *_: 'Dog')
+
+    assert schema.get_type('MyType') == MyType
+
+
+def test_schema_introspect():
+    schema = Schema(name='My own schema')
+
+    class MyType(ObjectType):
+        type = StringField(resolve=lambda *_: 'Dog')
+
+    schema.query = MyType
+
+    introspection = schema.introspect()
+    assert '__schema' in introspection
+
diff --git a/tests/relay/test_relayfields.py b/tests/relay/test_relayfields.py
new file mode 100644
index 00000000..5285a219
--- /dev/null
+++ b/tests/relay/test_relayfields.py
@@ -0,0 +1,43 @@
+from pytest import raises
+
+import graphene
+from graphene import relay
+
+schema = graphene.Schema()
+
+
+class MyType(object):
+    name = 'my'
+
+
+class MyNode(relay.Node):
+    name = graphene.StringField()
+
+    @classmethod
+    def get_node(cls, id):
+        return MyNode(MyType())
+
+
+class Query(graphene.ObjectType):
+    my_node = relay.NodeField(MyNode)
+
+
+schema.query = Query
+
+
+def test_nodefield_query():
+    query = '''
+    query RebelsShipsQuery {
+      myNode(id:"TXlOb2RlOjE=") {
+        name
+      }
+    }
+    '''
+    expected = {
+        'myNode': {
+            'name': 'my'
+        }
+    }
+    result = schema.execute(query)
+    assert not result.errors
+    assert result.data == expected
diff --git a/tests/starwars_django/data.py b/tests/starwars_django/data.py
index cb43c29b..bf88b7a9 100644
--- a/tests/starwars_django/data.py
+++ b/tests/starwars_django/data.py
@@ -1,18 +1,28 @@
-from collections import namedtuple
-
-from .models import Ship, Faction
+from .models import Ship, Faction, Character
 
 
 def initialize():
+    human = Character(
+        name='Human'
+    )
+    human.save()
+
+    droid = Character(
+        name='Droid'
+    )
+    droid.save()
+
     rebels = Faction(
         id='1',
         name='Alliance to Restore the Republic',
+        hero=human
     )
     rebels.save()
 
     empire = Faction(
         id='2',
         name='Galactic Empire',
+        hero=droid
     )
     empire.save()
 
diff --git a/tests/starwars_django/models.py b/tests/starwars_django/models.py
index 6afa152e..10050c33 100644
--- a/tests/starwars_django/models.py
+++ b/tests/starwars_django/models.py
@@ -2,8 +2,16 @@ from __future__ import absolute_import
 from django.db import models
 
 
+class Character(models.Model):
+    name = models.CharField(max_length=50)
+
+    def __str__(self):
+        return self.name
+
+
 class Faction(models.Model):
     name = models.CharField(max_length=50)
+    hero = models.ForeignKey(Character)
 
     def __str__(self):
         return self.name
diff --git a/tests/starwars_django/schema.py b/tests/starwars_django/schema.py
index 0bde6826..1949da6a 100644
--- a/tests/starwars_django/schema.py
+++ b/tests/starwars_django/schema.py
@@ -4,7 +4,8 @@ from graphene.contrib.django import (
     DjangoObjectType,
     DjangoNode
 )
-from .models import Ship as ShipModel, Faction as FactionModel
+from .models import (
+    Ship as ShipModel, Faction as FactionModel, Character as CharacterModel)
 from .data import (
     getFaction,
     getShip,
@@ -17,7 +18,6 @@ schema = graphene.Schema(name='Starwars Django Relay Schema')
 
 
 class Ship(DjangoNode):
-
     class Meta:
         model = ShipModel
 
@@ -26,8 +26,13 @@ class Ship(DjangoNode):
         return Ship(getShip(id))
 
 
-class Faction(DjangoNode):
+@schema.register
+class CharacterModel(DjangoObjectType):
+    class Meta:
+        model = CharacterModel
 
+
+class Faction(DjangoNode):
     class Meta:
         model = FactionModel
 
diff --git a/tests/starwars_django/test_connections.py b/tests/starwars_django/test_connections.py
index e7181dc9..9992f0f3 100644
--- a/tests/starwars_django/test_connections.py
+++ b/tests/starwars_django/test_connections.py
@@ -14,6 +14,9 @@ def test_correct_fetch_first_ship_rebels():
     query RebelsShipsQuery {
       rebels {
         name,
+        hero {
+          name
+        }
         ships(first: 1) {
           edges {
             node {
@@ -27,6 +30,9 @@ def test_correct_fetch_first_ship_rebels():
     expected = {
         'rebels': {
             'name': 'Alliance to Restore the Republic',
+            'hero': {
+                'name': 'Human'
+            },
             'ships': {
                 'edges': [
                     {