Repository: chainer/chainer

Issue:
Use pep8 v. 1.7.0
pep8 v. 1.7.0 is now available. It checks more coding errors.
https://pypi.python.org/pypi/pep8/1.7.0

We need to pass all tests.



Discussion:

Resolving patch:
diff --git a/chainer/computational_graph.py b/chainer/computational_graph.py
--- a/chainer/computational_graph.py
+++ b/chainer/computational_graph.py
@@ -83,10 +83,10 @@ def _to_dot(self):
             ret += DotNode(node).label
         for edge in self.edges:
             head, tail = edge
-            assert (isinstance(head, variable.Variable)
-                    and isinstance(tail, function.Function)) or \
-                   (isinstance(head, function.Function)
-                    and isinstance(tail, variable.Variable))
+            assert (isinstance(head, variable.Variable) and
+                    isinstance(tail, function.Function)) or \
+                   (isinstance(head, function.Function) and
+                    isinstance(tail, variable.Variable))
             head_node = DotNode(head)
             tail_node = DotNode(tail)
             ret += "%s -> %s;" % (head_node.id_, tail_node.id_)
diff --git a/chainer/functions/noise/dropout.py b/chainer/functions/noise/dropout.py
--- a/chainer/functions/noise/dropout.py
+++ b/chainer/functions/noise/dropout.py
@@ -23,8 +23,8 @@ def forward(self, x):
         if xp == numpy:
             flag = xp.random.rand(*x[0].shape) >= self.dropout_ratio
         else:
-            flag = (xp.random.rand(*x[0].shape, dtype=numpy.float32)
-                    >= self.dropout_ratio)
+            flag = (xp.random.rand(*x[0].shape, dtype=numpy.float32) >=
+                    self.dropout_ratio)
         self.mask = scale * flag
         return x[0] * self.mask,
 
diff --git a/chainer/gradient_check.py b/chainer/gradient_check.py
--- a/chainer/gradient_check.py
+++ b/chainer/gradient_check.py
@@ -3,6 +3,7 @@
 
 from chainer import cuda
 from chainer import utils
+from chainer import variable
 
 
 def _copy_arrays(xs):
@@ -114,3 +115,151 @@ def assert_allclose(x, y, atol=1e-5, rtol=1e-4, verbose=True):
     except Exception:
         print('error:', numpy.abs(x - y).max())
         raise
+
+
+def _as_tuple(x):
+    if isinstance(x, tuple):
+        return x
+    elif isinstance(x, list):
+        return tuple(x)
+    else:
+        return (x,)
+
+
+def check_backward(func, x_data, y_grad, params=(),
+                   eps=1e-3, atol=1e-5, rtol=1e-4):
+    """Test backward procedure of a given function.
+
+    This function automatically check backward-process of given function.
+    For example, when you have a :class:`~chainer.Function` class ``MyFunc``,
+    that gets two arguments and returns one value, you can make its test like
+    this::
+
+    >> def test_my_func(self):
+    >>   func = MyFunc()
+    >>   x1_data = xp.array(...)
+    >>   x2_data = xp.array(...)
+    >>   gy_data = xp.array(...)
+    >>   check_backward(func, (x1_data, x2_data), gy_data)
+
+    This method creates :class:`~chainer.Variable` objects with ``x_data``
+    and calls ``func`` with the :class:`~chainer.Variable`s to get its result
+    as :class:`~chainer.Variable`.
+    Then, it sets ``y_grad`` array to ``grad`` attribute of the result and
+    calls ``backward`` method to get gradients of the inputs.
+    To check correctness of the gradients, the function calls
+    :func:`numerical_grad` to calculate numerically the gradients and compares
+    the types of gradients with :func:`assert_allclose`.
+    If input objects (``x1_data`` or/and ``x2_data`` in this example) represent
+    integer variables, their gradients are ignored.
+
+    You can simplify a test when ``MyFunc`` gets only one argument::
+
+    >>   check_backward(func, x1_data, gy_data)
+
+    If ``MyFunc`` is a loss function which returns a zero-dimensional
+    array, pass ``None`` to ``gy_data``. In this case, it sets ``1`` to
+    ``grad`` attribute of the result::
+
+    >>   check_backward(my_loss_func, (x1_data, x2_data), None)
+
+    If ``MyFunc`` returns multiple outputs, pass all gradients for outputs
+    as a tuple::
+
+    >>   gy1_data = xp.array(...)
+    >>   gy2_data = xp.array(...)
+    >>   check_backward(func, x1_data, (gy1_data, gy2_data))
+
+    You can also test a :class:`~chainer.Link`.
+    To check gradients of parameters of the link, set a tuple of the parameters
+    to ``params`` arguments::
+
+    >>   check_backward(my_link, (x1_data, x2_data), gy_data,
+    >>                  (my_link.W, my_link.b))
+
+    Note that ``params`` are not ``ndarray``s, but ``~chainer.Variables``s.
+
+    Function objects are acceptable as ``func`` argument::
+
+    >>   check_backward(lambda x1, x2: f(x1, x2),
+    >>                  (x1_data, x2_data), gy_data)
+
+    .. note::
+
+       ``func`` is called many times to get numerical gradients for all inputs.
+       This function doesn't work correctly when ``func`` behaves randomly as
+       it gets different gradients.
+
+
+    Args:
+        func (callable): A function which gets :class:`~chainer.Variable`s
+            and returns :class:`~chainer.Variable`s. ``func`` must returns
+            a tuple of :class:`~chainer.Variable`s or one
+            :class:`~chainer.Variable`. You can use :class:`~chainer.Function`
+            object, :class:`~chainer.Link` object or a function satisfying the
+            condition.
+        x_data (ndarray or tuple of ndarrays): A set of ``ndarray``s to be
+            passed to ``func``. If ``x_data`` is one ``ndarray`` object, it is
+            treated as ``(x_data,)``.
+        y_grad (ndarray or tuple of ndarrays or None):
+            A set of ``ndarray``s representing gradinents of return-values of
+            ``func``. If ``y_grad`` is one ``ndarray`` object, it is
+            treated as ``(y_grad,)``. If ``func`` is a loss-function, set
+            ``y_grad = None``.
+        params (~chainer.Variable or tuple of ~chainder.Variable):
+            A set of :class:`~chainer.Variable`s whose gradients are checked.
+            When ``func`` is a ``~chainer.Link`` object, set its parameters
+            as ``params``. If ``params`` is one ~chainer.Variable object, it is
+            treated as ``(params,)``.
+        eps (float): Epsilon value to be passed to :func:`numerical_grad`.
+        atol (float): Absolute tolerance to be passed to
+            :func:`assert_allclose`.
+        rtol (float): Relative tolerance to be passed to
+            :func:`assert_allclose`.
+
+    See:
+       :func:`numerical_grad`
+    """
+    x_data = _as_tuple(x_data)
+    if y_grad is not None:
+        y_grad = _as_tuple(y_grad)
+    params = _as_tuple(params)
+
+    xs = [variable.Variable(x) for x in x_data]
+    y = func(*xs)
+    y = _as_tuple(y)
+
+    if y_grad is not None:
+        if len(y) != len(y_grad):
+            raise ValueError(
+                '`y_grad` must have the same length of output values')
+        for iy, igy in zip(y, y_grad):
+            iy.grad = igy
+    else:
+        if len(y) != 1:
+            raise ValueError(
+                'When `y_grad` is `None`, the function must return a'
+                'zero-dimentional array')
+        y_grad = (1,)
+
+    # We only need to call `backward` for one result `Variable`.
+    # `Variable.backward` method calls `Function.backward` of its creator.
+    y[0].backward()
+
+    def f():
+        ys = func(*xs)
+        ys = _as_tuple(ys)
+        return tuple(y.data for y in ys)
+
+    for x in xs:
+        if x.data.dtype.kind == 'f':
+            gx, = numerical_grad(f, (x.data,), y_grad, eps=eps)
+            assert_allclose(gx, x.grad, atol=atol, rtol=rtol)
+            assert gx.dtype is x.grad.dtype
+        else:
+            assert x.grad is None
+
+    for p in params:
+        gp, = numerical_grad(f, (p.data,), y_grad, eps=eps)
+        assert_allclose(gp, p.grad, atol=atol, rtol=rtol)
+        assert gp.dtype is p.grad.dtype


Test patch:
diff --git a/cupy/testing/helper.py b/cupy/testing/helper.py
--- a/cupy/testing/helper.py
+++ b/cupy/testing/helper.py
@@ -34,11 +34,9 @@ def _check_cupy_numpy_error(self, cupy_error, cupy_tb, numpy_error,
     if cupy_error is None and numpy_error is None:
         self.fail('Both cupy and numpy are expected to raise errors, but not')
     elif cupy_error is None:
-        self.fail('Only numpy raises error\n\n'
-                  + numpy_tb)
+        self.fail('Only numpy raises error\n\n' + numpy_tb)
     elif numpy_error is None:
-        self.fail('Only cupy raises error\n\n'
-                  + cupy_tb)
+        self.fail('Only cupy raises error\n\n' + cupy_tb)
     elif type(cupy_error) is not type(numpy_error):
         msg = '''Differnet types of errors occurred
 
diff --git a/tests/chainer_tests/functions_tests/activation_tests/test_clipped_relu.py b/tests/chainer_tests/functions_tests/activation_tests/test_clipped_relu.py
--- a/tests/chainer_tests/functions_tests/activation_tests/test_clipped_relu.py
+++ b/tests/chainer_tests/functions_tests/activation_tests/test_clipped_relu.py
@@ -43,17 +43,8 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = functions.clipped_relu(x, self.z)
-        self.assertEqual(y.data.dtype, numpy.float32)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.ClippedReLU(self.z), x_data, y_grad)
 
     def test_backward_cpu(self):
         self.check_backward(self.x, self.gy)
diff --git a/tests/chainer_tests/functions_tests/activation_tests/test_elu.py b/tests/chainer_tests/functions_tests/activation_tests/test_elu.py
--- a/tests/chainer_tests/functions_tests/activation_tests/test_elu.py
+++ b/tests/chainer_tests/functions_tests/activation_tests/test_elu.py
@@ -45,16 +45,8 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = functions.elu(x, alpha=self.alpha)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.ELU(self.alpha), x_data, y_grad)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/activation_tests/test_leaky_relu.py b/tests/chainer_tests/functions_tests/activation_tests/test_leaky_relu.py
--- a/tests/chainer_tests/functions_tests/activation_tests/test_leaky_relu.py
+++ b/tests/chainer_tests/functions_tests/activation_tests/test_leaky_relu.py
@@ -45,16 +45,8 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = functions.leaky_relu(x, slope=self.slope)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.LeakyReLU(self.slope), x_data, y_grad)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/activation_tests/test_lstm.py b/tests/chainer_tests/functions_tests/activation_tests/test_lstm.py
--- a/tests/chainer_tests/functions_tests/activation_tests/test_lstm.py
+++ b/tests/chainer_tests/functions_tests/activation_tests/test_lstm.py
@@ -72,20 +72,9 @@ def test_flat_forward_gpu(self):
         self.test_forward_gpu()
 
     def check_backward(self, c_prev_data, x_data, c_grad, h_grad):
-        c_prev = chainer.Variable(c_prev_data)
-        x = chainer.Variable(x_data)
-        c, h = functions.lstm(c_prev, x)
-        c.grad = c_grad
-        h.grad = h_grad
-        c.backward()
-
-        func = c.creator
-        f = lambda: func.forward((c_prev.data, x.data))
-        gc_prev, gx = gradient_check.numerical_grad(
-            f, (c_prev.data, x.data), (c_grad, h_grad), eps=1e-2)
-
-        gradient_check.assert_allclose(gc_prev, c_prev.grad)
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.LSTM(),
+            (c_prev_data, x_data), (c_grad, h_grad), eps=1e-2)
 
     @condition.retry(3)
     def test_full_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/activation_tests/test_maxout.py b/tests/chainer_tests/functions_tests/activation_tests/test_maxout.py
--- a/tests/chainer_tests/functions_tests/activation_tests/test_maxout.py
+++ b/tests/chainer_tests/functions_tests/activation_tests/test_maxout.py
@@ -6,6 +6,7 @@
 import chainer
 from chainer import cuda
 from chainer import functions
+from chainer.functions.activation import maxout
 from chainer import gradient_check
 from chainer import testing
 from chainer.testing import attr
@@ -79,31 +80,13 @@ def test_forward_gpu(self):
             b, cuda.to_gpu(self.y))
 
     def check_backward(self, x_data, W_data, b_data, y_grad):
-        x = chainer.Variable(x_data)
-        W = chainer.Variable(W_data)
-        if b_data is None:
-            y = functions.maxout(x, W)
-        else:
-            b = chainer.Variable(b_data)
-            y = functions.maxout(x, W, b)
-
-        y.grad = y_grad
-        y.backward()
-        func = y.creator
-
-        if b_data is None:
-            f = lambda: func.forward((x.data, W.data))
-            gx, gW = gradient_check.numerical_grad(
-                f, (x.data, W.data), (y.grad, ), eps=1e-2)
-        else:
-            f = lambda: func.forward((x.data, W.data, b.data))
-            gx, gW, gb = gradient_check.numerical_grad(
-                f, (x.data, W.data, b.data), (y.grad, ), eps=1e-2)
-
-        gradient_check.assert_allclose(gx, x.grad, atol=1e-2)
-        gradient_check.assert_allclose(gW, W.grad, atol=1e-2)
+        args = (x_data, W_data)
         if b_data is not None:
-            gradient_check.assert_allclose(gb, b.grad, atol=1e-2)
+            args = args + (b_data,)
+
+        gradient_check.check_backward(
+            maxout.MaxoutFunction(), args, y_grad,
+            eps=1e-2, atol=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/activation_tests/test_relu.py b/tests/chainer_tests/functions_tests/activation_tests/test_relu.py
--- a/tests/chainer_tests/functions_tests/activation_tests/test_relu.py
+++ b/tests/chainer_tests/functions_tests/activation_tests/test_relu.py
@@ -2,7 +2,6 @@
 
 import numpy
 
-import chainer
 from chainer import cuda
 from chainer import functions
 from chainer import gradient_check
@@ -22,17 +21,8 @@ def setUp(self):
         self.gy = numpy.random.uniform(-1, 1, (3, 2)).astype(numpy.float32)
 
     def check_backward(self, x_data, y_grad, use_cudnn=True):
-        x = chainer.Variable(x_data)
-        y = functions.relu(x, use_cudnn=use_cudnn)
-        self.assertEqual(y.data.dtype, numpy.float32)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.ReLU(use_cudnn), x_data, y_grad)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/activation_tests/test_sigmoid.py b/tests/chainer_tests/functions_tests/activation_tests/test_sigmoid.py
--- a/tests/chainer_tests/functions_tests/activation_tests/test_sigmoid.py
+++ b/tests/chainer_tests/functions_tests/activation_tests/test_sigmoid.py
@@ -33,16 +33,8 @@ def test_forward_gpu_no_cudnn(self):
         self.test_forward_gpu(False)
 
     def check_backward(self, x_data, y_grad, use_cudnn=True):
-        x = chainer.Variable(x_data)
-        y = functions.sigmoid(x, use_cudnn=use_cudnn)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.Sigmoid(use_cudnn), x_data, y_grad)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/activation_tests/test_softmax.py b/tests/chainer_tests/functions_tests/activation_tests/test_softmax.py
--- a/tests/chainer_tests/functions_tests/activation_tests/test_softmax.py
+++ b/tests/chainer_tests/functions_tests/activation_tests/test_softmax.py
@@ -47,16 +47,8 @@ def test_forward_gpu_no_cudnn(self):
         self.check_forward(cuda.to_gpu(self.x), False)
 
     def check_backward(self, x_data, gy_data, use_cudnn=True):
-        x = chainer.Variable(x_data)
-        y = functions.softmax(x, use_cudnn)
-        y.grad = gy_data
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,), eps=1e-2)
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.Softmax(use_cudnn), x_data, gy_data, eps=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/activation_tests/test_softplus.py b/tests/chainer_tests/functions_tests/activation_tests/test_softplus.py
--- a/tests/chainer_tests/functions_tests/activation_tests/test_softplus.py
+++ b/tests/chainer_tests/functions_tests/activation_tests/test_softplus.py
@@ -26,17 +26,8 @@ def check_forward(self, x_data):
         gradient_check.assert_allclose(y_exp, y.data)
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = functions.softplus(x, beta=self.beta)
-        self.assertEqual(y.data.dtype, numpy.float32)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.Softplus(beta=self.beta), x_data, y_grad)
 
     @condition.retry(3)
     def test_forward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/activation_tests/test_tanh.py b/tests/chainer_tests/functions_tests/activation_tests/test_tanh.py
--- a/tests/chainer_tests/functions_tests/activation_tests/test_tanh.py
+++ b/tests/chainer_tests/functions_tests/activation_tests/test_tanh.py
@@ -32,15 +32,8 @@ def test_forward_gpu_no_cudnn(self):
         self.test_forward_gpu(False)
 
     def check_backward(self, x_data, gy_data, use_cudnn=True):
-        x = chainer.Variable(x_data)
-        y = functions.tanh(x, use_cudnn=use_cudnn)
-        y.grad = gy_data
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.Tanh(use_cudnn), x_data, gy_data)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/array_tests/test_broadcast.py b/tests/chainer_tests/functions_tests/array_tests/test_broadcast.py
--- a/tests/chainer_tests/functions_tests/array_tests/test_broadcast.py
+++ b/tests/chainer_tests/functions_tests/array_tests/test_broadcast.py
@@ -51,22 +51,8 @@ def test_forward_gpu(self):
         self.check_forward([cuda.to_gpu(x) for x in self.data])
 
     def check_backward(self, data, grads):
-        xs = [chainer.Variable(x) for x in data]
-        bxs = functions.broadcast(*xs)
-
-        # When len(xs) == 1, function returns a Variable object
-        if isinstance(bxs, chainer.Variable):
-            bxs = (bxs,)
-
-        func = bxs[0].creator
-        f = lambda: func.forward(data)
-
-        for i, (bx, grad) in enumerate(zip(bxs, grads)):
-            bx.grad = grad
-            bx.backward()
-            gxs = gradient_check.numerical_grad(
-                f, data, tuple(bx.grad for bx in bxs))
-            gradient_check.assert_allclose(gxs[i], xs[i].grad)
+        gradient_check.check_backward(
+            functions.Broadcast(), data, grads)
 
     def test_backward_cpu(self):
         self.check_backward(self.data, self.grads)
@@ -128,16 +114,8 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.data))
 
     def check_backward(self, data, grad):
-        x = chainer.Variable(data)
-        bx = functions.broadcast_to(x, self.out_shape)
-
-        func = bx.creator
-        f = lambda: func.forward((data,))
-
-        bx.grad = grad
-        bx.backward()
-        gx, = gradient_check.numerical_grad(f, (data,), (bx.grad,))
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.BroadcastTo(self.out_shape), data, grad)
 
     def test_backward_cpu(self):
         self.check_backward(self.data, self.grad)
diff --git a/tests/chainer_tests/functions_tests/array_tests/test_expand_dims.py b/tests/chainer_tests/functions_tests/array_tests/test_expand_dims.py
--- a/tests/chainer_tests/functions_tests/array_tests/test_expand_dims.py
+++ b/tests/chainer_tests/functions_tests/array_tests/test_expand_dims.py
@@ -35,16 +35,8 @@ def check_forward(self, x_data):
         numpy.testing.assert_array_equal(cuda.to_cpu(y.data), y_expect)
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = functions.expand_dims(x, self.axis)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x_data,))
-        gx, = gradient_check.numerical_grad(f, (x_data,), (y_grad,))
-        gradient_check.assert_allclose(cuda.to_cpu(x.grad),
-                                       cuda.to_cpu(gx))
+        gradient_check.check_backward(
+            functions.ExpandDims(self.axis), x_data, y_grad)
 
     def test_forward_cpu(self):
         self.check_forward(self.x)
diff --git a/tests/chainer_tests/functions_tests/array_tests/test_reshape.py b/tests/chainer_tests/functions_tests/array_tests/test_reshape.py
--- a/tests/chainer_tests/functions_tests/array_tests/test_reshape.py
+++ b/tests/chainer_tests/functions_tests/array_tests/test_reshape.py
@@ -5,6 +5,7 @@
 import chainer
 from chainer import cuda
 from chainer import functions
+from chainer import gradient_check
 from chainer import testing
 from chainer.testing import attr
 
@@ -31,13 +32,8 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = functions.reshape(x, self.gy.shape)
-        y.grad = y_grad
-        y.backward()
-
-        shape = self.x.shepe
-        self.assertTrue((self.gy.reshape(shape) == cuda.to_cpu(x.grad)).all())
+        gradient_check.check_backward(
+            functions.Reshape(self.gy.shape), x_data, y_grad)
 
 
 class TestReshapeUnknownDimension(TestReshape):
diff --git a/tests/chainer_tests/functions_tests/array_tests/test_select_item.py b/tests/chainer_tests/functions_tests/array_tests/test_select_item.py
--- a/tests/chainer_tests/functions_tests/array_tests/test_select_item.py
+++ b/tests/chainer_tests/functions_tests/array_tests/test_select_item.py
@@ -39,18 +39,9 @@ def test_forward_gpu(self):
                            cuda.to_gpu(self.t_data))
 
     def check_backward(self, x_data, t_data, gy_data):
-        x = chainer.Variable(x_data)
-        t = chainer.Variable(t_data)
-        y = functions.select_item(x, t)
-        y.grad = gy_data
-        y.backward()
-        self.assertEqual(None, t.grad)
-
-        func = y.creator
-        f = lambda: func.forward((x.data, t.data))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (gy_data,), eps=0.01)
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.SelectItem(),
+            (x_data, t_data), gy_data, eps=0.01)
 
     def test_backward_cpu(self):
         self.check_backward(self.x_data, self.t_data, self.gy_data)
diff --git a/tests/chainer_tests/functions_tests/array_tests/test_swapaxes.py b/tests/chainer_tests/functions_tests/array_tests/test_swapaxes.py
--- a/tests/chainer_tests/functions_tests/array_tests/test_swapaxes.py
+++ b/tests/chainer_tests/functions_tests/array_tests/test_swapaxes.py
@@ -34,16 +34,9 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = functions.swapaxes(x, self.axis1, self.axis2)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data.copy(),))
-
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,), eps=1e-5)
-        gradient_check.assert_allclose(gx, x.grad, rtol=1e-5)
+        gradient_check.check_backward(
+            functions.Swapaxes(self.axis1, self.axis2),
+            x_data, y_grad, eps=1e-5, rtol=1e-5)
 
     def test_backward_cpu(self):
         self.check_backward(self.x, self.gy)
diff --git a/tests/chainer_tests/functions_tests/array_tests/test_transpose.py b/tests/chainer_tests/functions_tests/array_tests/test_transpose.py
--- a/tests/chainer_tests/functions_tests/array_tests/test_transpose.py
+++ b/tests/chainer_tests/functions_tests/array_tests/test_transpose.py
@@ -32,17 +32,9 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = functions.transpose(x, self.axes)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data.copy(),))
-
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,), eps=1e-5)
-
-        gradient_check.assert_allclose(gx, x.grad, rtol=1e-5)
+        gradient_check.check_backward(
+            functions.Transpose(self.axes),
+            x_data, y_grad, eps=1e-5, rtol=1e-5)
 
     def test_backward_cpu(self):
         self.check_backward(self.x, self.gy)
diff --git a/tests/chainer_tests/functions_tests/array_tests/test_where.py b/tests/chainer_tests/functions_tests/array_tests/test_where.py
--- a/tests/chainer_tests/functions_tests/array_tests/test_where.py
+++ b/tests/chainer_tests/functions_tests/array_tests/test_where.py
@@ -49,22 +49,8 @@ def test_forward_gpu(self):
                            cuda.to_gpu(self.y_data))
 
     def check_backward(self, c_data, x_data, y_data, g_data):
-        c = chainer.Variable(c_data)
-        x = chainer.Variable(x_data)
-        y = chainer.Variable(y_data)
-
-        z = F.where(c, x, y)
-        z.grad = g_data
-
-        z.backward()
-
-        func = z.creator
-        f = lambda: func.forward((c.data, x.data, y.data))
-
-        gx, gy = gradient_check.numerical_grad(f, (x_data, y.data), (g_data,))
-        gradient_check.assert_allclose(gx, x.grad)
-        gradient_check.assert_allclose(gy, y.grad)
-        self.assertIs(c.grad, None)
+        gradient_check.check_backward(
+            F.Where(), (c_data, x_data, y_data), g_data)
 
     def test_backward_cpu(self):
         self.check_backward(self.c_data, self.x_data, self.y_data, self.g_data)
diff --git a/tests/chainer_tests/functions_tests/connection_tests/test_convolution_2d.py b/tests/chainer_tests/functions_tests/connection_tests/test_convolution_2d.py
--- a/tests/chainer_tests/functions_tests/connection_tests/test_convolution_2d.py
+++ b/tests/chainer_tests/functions_tests/connection_tests/test_convolution_2d.py
@@ -5,6 +5,7 @@
 import chainer
 from chainer import cuda
 from chainer import functions
+from chainer.functions.connection import convolution_2d
 from chainer import gradient_check
 from chainer import testing
 from chainer.testing import attr
@@ -60,30 +61,14 @@ def test_forward_consistency_im2col_nobias(self):
         self.test_forward_consistency(nobias=True)
 
     def check_backward(self, x_data, W_data, b_data, y_grad):
-        x = chainer.Variable(x_data)
-        W = chainer.Variable(W_data)
-        b = None if b_data is None else chainer.Variable(b_data)
-        y = functions.convolution_2d(
-            x, W, b, stride=self.stride, pad=self.pad,
-            use_cudnn=self.use_cudnn)
-
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        if b is None:
-            f = lambda: func.forward((x.data, W.data))
-            gx, gW = gradient_check.numerical_grad(
-                f, (x.data, W.data), (y.grad,), eps=1e-2)
-        else:
-            f = lambda: func.forward((x.data, W.data, b.data))
-            gx, gW, gb = gradient_check.numerical_grad(
-                f, (x.data, W.data, b.data), (y.grad,), eps=1e-2)
-
-        gradient_check.assert_allclose(gx, x.grad)
-        gradient_check.assert_allclose(gW, W.grad)
-        if b is not None:
-            gradient_check.assert_allclose(gb, b.grad)
+        args = (x_data, W_data)
+        if b_data is not None:
+            args = args + (b_data,)
+
+        gradient_check.check_backward(
+            convolution_2d.Convolution2DFunction(
+                self.stride, self.pad, self.use_cudnn),
+            args, y_grad, eps=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/connection_tests/test_deconvolution_2d.py b/tests/chainer_tests/functions_tests/connection_tests/test_deconvolution_2d.py
--- a/tests/chainer_tests/functions_tests/connection_tests/test_deconvolution_2d.py
+++ b/tests/chainer_tests/functions_tests/connection_tests/test_deconvolution_2d.py
@@ -5,6 +5,7 @@
 import chainer
 from chainer import cuda
 import chainer.functions as F
+from chainer.functions.connection import deconvolution_2d
 from chainer import gradient_check
 from chainer import testing
 from chainer.testing import attr
@@ -79,29 +80,14 @@ def test_forward_consistency_im2col(self):
         self.test_forward_consistency()
 
     def check_backward(self, x_data, W_data, b_data, y_grad):
-        x = chainer.Variable(x_data)
-        W = chainer.Variable(W_data)
-        b = None if b_data is None else chainer.Variable(b_data)
-        y = F.deconvolution_2d(x, W, b, stride=self.stride, pad=self.pad,
-                               use_cudnn=self.use_cudnn)
-
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        if b is None:
-            f = lambda: func.forward((x.data, W.data))
-            gx, gW = gradient_check.numerical_grad(
-                f, (x.data, W.data), (y.grad,), eps=1e-2)
-        else:
-            f = lambda: func.forward((x.data, W.data, b.data))
-            gx, gW, gb = gradient_check.numerical_grad(
-                f, (x.data, W.data, b.data), (y.grad,), eps=1e-2)
-
-        gradient_check.assert_allclose(gx, x.grad)
-        gradient_check.assert_allclose(gW, W.grad)
-        if b is not None:
-            gradient_check.assert_allclose(gb, b.grad)
+        args = (x_data, W_data)
+        if b_data is not None:
+            args = args + (b_data,)
+
+        gradient_check.check_backward(
+            deconvolution_2d.Deconvolution2DFunction(
+                self.stride, self.pad, self.outsize, self.use_cudnn),
+            args, y_grad, eps=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/connection_tests/test_linear.py b/tests/chainer_tests/functions_tests/connection_tests/test_linear.py
--- a/tests/chainer_tests/functions_tests/connection_tests/test_linear.py
+++ b/tests/chainer_tests/functions_tests/connection_tests/test_linear.py
@@ -5,6 +5,7 @@
 import chainer
 from chainer import cuda
 from chainer import functions
+from chainer.functions.connection import linear
 from chainer import gradient_check
 from chainer import testing
 from chainer.testing import attr
@@ -57,27 +58,12 @@ def test_forward_gpu_nobias(self):
             cuda.to_gpu(self.x.dot(self.W.T)))
 
     def check_backward(self, x_data, W_data, b_data, y_grad):
-        x = chainer.Variable(x_data)
-        W = chainer.Variable(W_data)
-        b = None if b_data is None else chainer.Variable(b_data)
-        y = functions.linear(x, W, b)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        if b_data is None:
-            f = lambda: func.forward((x.data, W.data))
-            gx, gW = gradient_check.numerical_grad(
-                f, (x.data, W.data), (y.grad,), eps=1e-2)
-        else:
-            f = lambda: func.forward((x.data, W.data, b.data))
-            gx, gW, gb = gradient_check.numerical_grad(
-                f, (x.data, W.data, b.data), (y.grad,), eps=1e-2)
-
-        gradient_check.assert_allclose(gx, x.grad)
-        gradient_check.assert_allclose(gW, W.grad)
+        args = (x_data, W_data)
         if b_data is not None:
-            gradient_check.assert_allclose(gb, b.grad)
+            args = args + (b_data,)
+
+        gradient_check.check_backward(
+            linear.LinearFunction(), args, y_grad, eps=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/loss_tests/test_contrastive.py b/tests/chainer_tests/functions_tests/loss_tests/test_contrastive.py
--- a/tests/chainer_tests/functions_tests/loss_tests/test_contrastive.py
+++ b/tests/chainer_tests/functions_tests/loss_tests/test_contrastive.py
@@ -66,20 +66,9 @@ def test_forward_gpu_no_cudnn(self):
                            cuda.to_gpu(self.t))
 
     def check_backward(self, x0_data, x1_data, t_data):
-        x0 = chainer.Variable(x0_data)
-        x1 = chainer.Variable(x1_data)
-        t = chainer.Variable(t_data)
-        loss = functions.contrastive(x0, x1, t, self.margin)
-        loss.backward()
-        self.assertEqual(None, t.grad)
-
-        func = loss.creator
-        f = lambda: func.forward((x0.data, x1.data, t.data))
-        gx0, = gradient_check.numerical_grad(f, (x0.data,), (1,))
-        gx1, = gradient_check.numerical_grad(f, (x1.data,), (1,))
-
-        gradient_check.assert_allclose(gx0, x0.grad, rtol=1e-4, atol=1e-4)
-        gradient_check.assert_allclose(gx1, x1.grad, rtol=1e-4, atol=1e-4)
+        gradient_check.check_backward(
+            functions.Contrastive(self.margin),
+            (x0_data, x1_data, t_data), None, rtol=1e-4, atol=1e-4)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/loss_tests/test_cross_covariance.py b/tests/chainer_tests/functions_tests/loss_tests/test_cross_covariance.py
--- a/tests/chainer_tests/functions_tests/loss_tests/test_cross_covariance.py
+++ b/tests/chainer_tests/functions_tests/loss_tests/test_cross_covariance.py
@@ -54,19 +54,8 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.y), cuda.to_gpu(self.z))
 
     def check_backward(self, y_data, z_data):
-        y = chainer.Variable(y_data)
-        z = chainer.Variable(z_data)
-        loss = functions.cross_covariance(y, z)
-        scaled_loss = 0.5 * loss
-        scaled_loss.backward()
-
-        func = loss.creator
-        f = lambda: func.forward((y.data, z.data))
-        gy, gz = gradient_check.numerical_grad(f, (y.data, z.data),
-                                               (0.5,), eps=0.02)
-
-        gradient_check.assert_allclose(gy, y.grad)
-        gradient_check.assert_allclose(gz, z.grad)
+        gradient_check.check_backward(
+            functions.CrossCovariance(), (y_data, z_data), None, eps=0.02)
 
     def check_type(self, y_data, z_data):
         y = chainer.Variable(y_data)
diff --git a/tests/chainer_tests/functions_tests/loss_tests/test_ctc.py b/tests/chainer_tests/functions_tests/loss_tests/test_ctc.py
--- a/tests/chainer_tests/functions_tests/loss_tests/test_ctc.py
+++ b/tests/chainer_tests/functions_tests/loss_tests/test_ctc.py
@@ -39,9 +39,9 @@ def alpha(self, x, l, t, u):
                 (self.alpha(x, l, t-1, u-1) + self.alpha(x, l, t-1, u))
         else:
             return x[t][l[u]] * \
-                (self.alpha(x, l, t-1, u-2)
-                 + self.alpha(x, l, t-1, u-1)
-                 + self.alpha(x, l, t-1, u))
+                (self.alpha(x, l, t-1, u-2) +
+                 self.alpha(x, l, t-1, u-1) +
+                 self.alpha(x, l, t-1, u))
 
     def check_forward(self, t_data, xs_data):
         x = tuple(chainer.Variable(x_data) for x_data in xs_data)
@@ -61,11 +61,11 @@ def check_forward(self, t_data, xs_data):
             loss_expect += -math.log(self.alpha(xt[b],
                                                 self.l[b],
                                                 self.x.shape[0]-1,
-                                                self.l[b].shape[0]-1)
-                                     + self.alpha(xt[b],
-                                                  self.l[b],
-                                                  self.x.shape[0]-1,
-                                                  self.l[b].shape[0]-2))
+                                                self.l[b].shape[0]-1) +
+                                     self.alpha(xt[b],
+                                                self.l[b],
+                                                self.x.shape[0]-1,
+                                                self.l[b].shape[0]-2))
         loss_expect /= batch_size
         self.assertAlmostEqual(loss_expect, loss_value, places=5)
 
@@ -79,21 +79,9 @@ def test_forward_gpu(self):
 
     # expected value(via numerical differentiation) from t_data
     def check_backward(self, t_data, xs_data):
-        xs = tuple(chainer.Variable(x_data) for x_data in xs_data)
-        t = chainer.Variable(t_data)
-        loss = functions.connectionist_temporal_classification(xs, t, 2)
-        loss.grad = self.g
-        loss.backward()
-
-        func = loss.creator
-        xs_data = tuple(x.data for x in xs)
-        f = lambda: func.forward((t.data,) + xs_data)
-        gl_0, gx_0, gx_1, gx_2, gx_3 = gradient_check.numerical_grad(
-            f, ((t.data,) + xs_data), (self.gx,))
-        gradient_check.assert_allclose(xs[0].grad, gx_0, atol=1e-04)
-        gradient_check.assert_allclose(xs[1].grad, gx_1, atol=1e-04)
-        gradient_check.assert_allclose(xs[2].grad, gx_2, atol=1e-04)
-        gradient_check.assert_allclose(xs[3].grad, gx_3, atol=1e-04)
+        gradient_check.check_backward(
+            functions.ConnectionistTemporalClassification(2),
+            (t_data,) + xs_data, self.g, atol=1e-4)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/loss_tests/test_hinge.py b/tests/chainer_tests/functions_tests/loss_tests/test_hinge.py
--- a/tests/chainer_tests/functions_tests/loss_tests/test_hinge.py
+++ b/tests/chainer_tests/functions_tests/loss_tests/test_hinge.py
@@ -61,17 +61,8 @@ def test_forward_gpu_l2(self):
         self.check_forward(cuda.to_gpu(self.x), cuda.to_gpu(self.t), 'L2')
 
     def check_backward(self, x_data, t_data, norm):
-        x = chainer.Variable(x_data)
-        t = chainer.Variable(t_data)
-        loss = functions.hinge(x, t, norm)
-        loss.backward()
-        self.assertEqual(None, t.grad)
-
-        func = loss.creator
-        f = lambda: func.forward((x.data, t.data))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (1,), eps=0.01)
-
-        gradient_check.assert_allclose(gx, x.grad, atol=1e-4)
+        gradient_check.check_backward(
+            functions.Hinge(norm), (x_data, t_data), None, eps=0.01, atol=1e-4)
 
     @condition.retry(3)
     def test_backward_cpu_l1(self):
diff --git a/tests/chainer_tests/functions_tests/loss_tests/test_mean_squared_error.py b/tests/chainer_tests/functions_tests/loss_tests/test_mean_squared_error.py
--- a/tests/chainer_tests/functions_tests/loss_tests/test_mean_squared_error.py
+++ b/tests/chainer_tests/functions_tests/loss_tests/test_mean_squared_error.py
@@ -43,20 +43,9 @@ def test_forwrad_gpu(self):
         self.check_forward(cuda.to_gpu(self.x0), cuda.to_gpu(self.x1))
 
     def check_backward(self, x0_data, x1_data):
-        x0 = chainer.Variable(x0_data)
-        x1 = chainer.Variable(x1_data)
-        loss = functions.mean_squared_error(x0, x1)
-        loss.backward()
-
-        func = loss.creator
-        f = lambda: func.forward((x0.data, x1.data))
-        gx0, gx1 = gradient_check.numerical_grad(
-            f, (x0.data, x1.data), (1,), eps=1e-2)
-
-        gradient_check.assert_allclose(gx0, x0.grad)
-        gradient_check.assert_allclose(gx1, x1.grad)
-        self.assertEqual(x0.grad.dtype, numpy.float32)
-        self.assertEqual(x1.grad.dtype, numpy.float32)
+        gradient_check.check_backward(
+            functions.MeanSquaredError(),
+            (x0_data, x1_data), None, eps=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/loss_tests/test_sigmoid_cross_entropy.py b/tests/chainer_tests/functions_tests/loss_tests/test_sigmoid_cross_entropy.py
--- a/tests/chainer_tests/functions_tests/loss_tests/test_sigmoid_cross_entropy.py
+++ b/tests/chainer_tests/functions_tests/loss_tests/test_sigmoid_cross_entropy.py
@@ -72,21 +72,13 @@ def test_forward_gpu_no_cudnn(self):
         self.check_forward(cuda.to_gpu(self.x), cuda.to_gpu(self.t), False)
 
     def check_backward(self, x_data, t_data, use_cudnn=True):
-        x = chainer.Variable(x_data)
-        t = chainer.Variable(t_data)
-        loss = functions.sigmoid_cross_entropy(x, t, use_cudnn)
-        loss.backward()
-        self.assertEqual(None, t.grad)
-
         # Skip too large case. That requires a long time.
         if self.shape[0] == 65536:
             return
 
-        func = loss.creator
-        f = lambda: func.forward((x.data, t.data))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (1,), eps=0.01)
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(
+            functions.SigmoidCrossEntropy(use_cudnn),
+            (x_data, t_data), None, eps=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/loss_tests/test_softmax_cross_entropy.py b/tests/chainer_tests/functions_tests/loss_tests/test_softmax_cross_entropy.py
--- a/tests/chainer_tests/functions_tests/loss_tests/test_softmax_cross_entropy.py
+++ b/tests/chainer_tests/functions_tests/loss_tests/test_softmax_cross_entropy.py
@@ -61,17 +61,9 @@ def test_forward_gpu_no_cudnn(self):
         self.check_forward(cuda.to_gpu(self.x), cuda.to_gpu(self.t), False)
 
     def check_backward(self, x_data, t_data, use_cudnn=True):
-        x = chainer.Variable(x_data)
-        t = chainer.Variable(t_data)
-        loss = functions.softmax_cross_entropy(x, t, use_cudnn)
-        loss.backward()
-        self.assertEqual(None, t.grad)
-
-        func = loss.creator
-        f = lambda: func.forward((x.data, t.data))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (1,), eps=0.02)
-
-        gradient_check.assert_allclose(gx, x.grad, atol=self.backward_atol)
+        gradient_check.check_backward(
+            functions.SoftmaxCrossEntropy(use_cudnn),
+            (x_data, t_data), None, eps=0.02, atol=self.backward_atol)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/loss_tests/test_vae.py b/tests/chainer_tests/functions_tests/loss_tests/test_vae.py
--- a/tests/chainer_tests/functions_tests/loss_tests/test_vae.py
+++ b/tests/chainer_tests/functions_tests/loss_tests/test_vae.py
@@ -20,9 +20,9 @@ def setUp(self):
         # Refer to Appendix B in the original paper
         # Auto-Encoding Variational Bayes (http://arxiv.org/abs/1312.6114)
         J = self.mean.size
-        self.expect = -(J + numpy.sum(self.ln_var)
-                        - numpy.sum(self.mean * self.mean)
-                        - numpy.sum(numpy.exp(self.ln_var))) * 0.5
+        self.expect = -(J + numpy.sum(self.ln_var) -
+                        numpy.sum(self.mean * self.mean) -
+                        numpy.sum(numpy.exp(self.ln_var))) * 0.5
 
     def check_gaussian_kl_divergence(self, mean, ln_var):
         m = chainer.Variable(mean)
@@ -50,8 +50,8 @@ def setUp(self):
         # Refer to Appendix C.1 in the original paper
         # Auto-Encoding Variational Bayes (http://arxiv.org/abs/1312.6114)
         p = 1 / (1 + numpy.exp(-self.y))
-        self.expect = - (numpy.sum(self.x * numpy.log(p))
-                         + numpy.sum((1 - self.x) * numpy.log(1 - p)))
+        self.expect = - (numpy.sum(self.x * numpy.log(p)) +
+                         numpy.sum((1 - self.x) * numpy.log(1 - p)))
 
     def check_bernoulli_nll(self, x_data, y_data):
         x = chainer.Variable(x_data)
@@ -83,9 +83,9 @@ def setUp(self):
         x_d = self.x - self.mean
         var = numpy.exp(self.ln_var)
 
-        self.expect = (0.5 * D * numpy.log(2 * numpy.pi)
-                       + 0.5 * numpy.sum(self.ln_var)
-                       + numpy.sum(x_d * x_d / var) * 0.5)
+        self.expect = (0.5 * D * numpy.log(2 * numpy.pi) +
+                       0.5 * numpy.sum(self.ln_var) +
+                       numpy.sum(x_d * x_d / var) * 0.5)
 
     def check_gaussian_nll(self, x_data, mean_data, ln_var_data):
         x = chainer.Variable(x_data)
diff --git a/tests/chainer_tests/functions_tests/math_tests/test_basic_math.py b/tests/chainer_tests/functions_tests/math_tests/test_basic_math.py
--- a/tests/chainer_tests/functions_tests/math_tests/test_basic_math.py
+++ b/tests/chainer_tests/functions_tests/math_tests/test_basic_math.py
@@ -129,18 +129,8 @@ def test_add_constant_allocation(self):
         self.assertEqual(1, z.data.get()[0])
 
     def check_backward(self, op, x1_data, x2_data, y_grad, atol):
-        x1 = chainer.Variable(x1_data)
-        x2 = chainer.Variable(x2_data)
-        y = op(x1, x2)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x1.data, x2.data))
-        gx1, gx2 = gradient_check.numerical_grad(
-            f, (x1.data, x2.data), (y.grad,))
-        gradient_check.assert_allclose(gx1, x1.grad, atol=atol)
-        gradient_check.assert_allclose(gx2, x2.grad, atol=atol)
+        gradient_check.check_backward(op, (x1_data, x2_data), y_grad,
+                                      atol=atol)
 
     def backward_cpu(self, op, atol=1e-5):
         self.check_backward(op, self.x1, self.x2, self.gy, atol)
@@ -554,16 +544,8 @@ def test_rpow_forward_gpu(self):
         self.forward_gpu(lambda x, y: y ** x)
 
     def check_backward(self, op, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = op(x, self.value)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(lambda x: op(x, self.value),
+                                      x_data, y_grad)
 
     def backward_cpu(self, op):
         self.check_backward(op, self.x, self.gy)
@@ -803,16 +785,9 @@ def check_backward(self, op, x_data, y_grad, gpu, positive):
             value = numpy.abs(value)
         if gpu:
             value = cuda.to_gpu(value)
-        x = chainer.Variable(x_data)
-        y = op(x, value)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
 
-        gradient_check.assert_allclose(gx, x.grad, atol=1e-4, rtol=1e-4)
+        gradient_check.check_backward(lambda x: op(x, value), x_data, y_grad,
+                                      atol=1e-4, rtol=1e-4)
 
     def backward_cpu(self, op, positive=False):
         self.check_backward(op, self.x, self.gy, False, positive)
@@ -946,16 +921,7 @@ def test_abs_forward_gpu(self):
         self.forward_gpu(lambda x: abs(x), lambda x: abs(x))
 
     def check_backward(self, op, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = op(x)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(op, x_data, y_grad)
 
     def backward_cpu(self, op):
         self.check_backward(op, self.x, self.gy)
@@ -1006,16 +972,8 @@ def setUp(self):
         self.gy = numpy.random.uniform(-1, 1, (3, 2)).astype(numpy.float32)
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = x ** 2
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad, atol=1e-4, rtol=1e-4)
+        gradient_check.check_backward(
+            lambda x: x ** 2, x_data, y_grad, atol=1e-4, rtol=1e-4)
 
     def test_cpu(self):
         self.check_backward(self.x, self.gy)
diff --git a/tests/chainer_tests/functions_tests/math_tests/test_exponential.py b/tests/chainer_tests/functions_tests/math_tests/test_exponential.py
--- a/tests/chainer_tests/functions_tests/math_tests/test_exponential.py
+++ b/tests/chainer_tests/functions_tests/math_tests/test_exponential.py
@@ -50,16 +50,7 @@ def test_log_forward_gpu(self):
         self.check_forward_gpu(F.log, numpy.log)
 
     def check_backward(self, op, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = op(x)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(op, x_data, y_grad)
 
     def check_backward_cpu(self, op):
         self.check_backward(op, self.x, self.gy)
diff --git a/tests/chainer_tests/functions_tests/math_tests/test_matmul.py b/tests/chainer_tests/functions_tests/math_tests/test_matmul.py
--- a/tests/chainer_tests/functions_tests/math_tests/test_matmul.py
+++ b/tests/chainer_tests/functions_tests/math_tests/test_matmul.py
@@ -30,18 +30,8 @@ def test_matmul_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x1), cuda.to_gpu(self.x2))
 
     def check_backward(self, x1_data, x2_data, y_grad, atol):
-        x1 = chainer.Variable(x1_data)
-        x2 = chainer.Variable(x2_data)
-        y = self.op(x1, x2)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x1.data, x2.data))
-        gx1, gx2 = gradient_check.numerical_grad(
-            f, (x1.data, x2.data), (y.grad,))
-        gradient_check.assert_allclose(gx1, x1.grad, atol=atol)
-        gradient_check.assert_allclose(gx2, x2.grad, atol=atol)
+        gradient_check.check_backward(
+            self.op, (x1_data, x2_data), y_grad, atol=atol)
 
     @condition.retry(3)
     def test_matmul_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/math_tests/test_minmax.py b/tests/chainer_tests/functions_tests/math_tests/test_minmax.py
--- a/tests/chainer_tests/functions_tests/math_tests/test_minmax.py
+++ b/tests/chainer_tests/functions_tests/math_tests/test_minmax.py
@@ -77,16 +77,9 @@ def test_forward_negative_multi_axis_invert_gpu(self):
         self.check_forward(cuda.to_gpu(self.x), axis=(-2, 0))
 
     def check_backward(self, x_data, y_grad, axis=None, keepdims=False):
-        x = chainer.Variable(x_data)
-        y = functions.max(x, axis=axis, keepdims=keepdims)
-
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data.copy(),))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,), eps=1e-5)
-        gradient_check.assert_allclose(gx, x.grad, rtol=1e-3, atol=1e-3)
+        gradient_check.check_backward(
+            functions.Max(axis, keepdims),
+            x_data, y_grad, eps=1e-5, rtol=1e-3, atol=1e-3)
 
     @condition.retry(3)
     def test_backward_cpu(self):
@@ -249,16 +242,9 @@ def test_forward_negative_multi_axis_invert_gpu(self):
         self.check_forward(cuda.to_gpu(self.x), axis=(-2, 0))
 
     def check_backward(self, x_data, y_grad, axis=None, keepdims=False):
-        x = chainer.Variable(x_data)
-        y = functions.min(x, axis=axis, keepdims=keepdims)
-
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data.copy(),))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,), eps=1e-5)
-        gradient_check.assert_allclose(gx, x.grad, rtol=1e-3, atol=1e-3)
+        gradient_check.check_backward(
+            functions.Min(axis=axis, keepdims=keepdims),
+            x_data, y_grad, eps=1e-4, rtol=1e-3, atol=1e-3)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/math_tests/test_sum.py b/tests/chainer_tests/functions_tests/math_tests/test_sum.py
--- a/tests/chainer_tests/functions_tests/math_tests/test_sum.py
+++ b/tests/chainer_tests/functions_tests/math_tests/test_sum.py
@@ -90,14 +90,8 @@ def test_forward_negative_multi_axis_invert_gpu(self):
         self.check_forward(cuda.to_gpu(self.x), axis=(-2, 0))
 
     def check_backward(self, x_data, y_grad, axis=None):
-        x = chainer.Variable(x_data)
-        y = functions.sum(x, axis=axis)
-
-        y.grad = y_grad
-        y.backward()
-
-        gx_expect = numpy.full_like(self.x, self.gy)
-        gradient_check.assert_allclose(gx_expect, x.grad)
+        gradient_check.check_backward(
+            functions.Sum(axis), x_data, y_grad)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/math_tests/test_trigonometric.py b/tests/chainer_tests/functions_tests/math_tests/test_trigonometric.py
--- a/tests/chainer_tests/functions_tests/math_tests/test_trigonometric.py
+++ b/tests/chainer_tests/functions_tests/math_tests/test_trigonometric.py
@@ -50,16 +50,7 @@ def test_sin_forward_gpu(self):
         self.check_forward_gpu(F.sin, numpy.sin)
 
     def check_backward(self, op, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = op(x)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
+        gradient_check.check_backward(op, x_data, y_grad)
 
     def check_backward_cpu(self, op):
         self.check_backward(op, self.x, self.gy)
diff --git a/tests/chainer_tests/functions_tests/noise_tests/test_gaussian.py b/tests/chainer_tests/functions_tests/noise_tests/test_gaussian.py
--- a/tests/chainer_tests/functions_tests/noise_tests/test_gaussian.py
+++ b/tests/chainer_tests/functions_tests/noise_tests/test_gaussian.py
@@ -2,7 +2,6 @@
 
 import numpy
 
-import chainer
 from chainer import cuda
 from chainer import functions
 from chainer import gradient_check
@@ -19,19 +18,9 @@ def setUp(self):
         self.gy = numpy.random.uniform(-1, 1, (3, 2)).astype(numpy.float32)
 
     def check_backward(self, m_data, v_data, y_grad):
-        m = chainer.Variable(m_data)
-        v = chainer.Variable(v_data)
-        y = functions.gaussian(m, v)
-        self.assertEqual(y.data.dtype, numpy.float32)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((m.data, v.data))
-        gm, gv = gradient_check.numerical_grad(f, (m.data, v.data), (y.grad,))
-
-        gradient_check.assert_allclose(gm, m.grad, atol=1e-4, rtol=1e-3)
-        gradient_check.assert_allclose(gv, v.grad, atol=1e-4, rtol=1e-3)
+        gradient_check.check_backward(
+            functions.Gaussian(), (m_data, v_data), y_grad,
+            atol=1e-4, rtol=1e-3)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/normalization_tests/test_local_response_normalization.py b/tests/chainer_tests/functions_tests/normalization_tests/test_local_response_normalization.py
--- a/tests/chainer_tests/functions_tests/normalization_tests/test_local_response_normalization.py
+++ b/tests/chainer_tests/functions_tests/normalization_tests/test_local_response_normalization.py
@@ -47,16 +47,9 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = functions.local_response_normalization(x)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,), eps=1)
-
-        gradient_check.assert_allclose(gx, x.grad, atol=1e-3)
+        gradient_check.check_backward(
+            functions.LocalResponseNormalization(), x_data, y_grad,
+            eps=1, atol=1e-4)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/pooling_tests/test_average_pooling_2d.py b/tests/chainer_tests/functions_tests/pooling_tests/test_average_pooling_2d.py
--- a/tests/chainer_tests/functions_tests/pooling_tests/test_average_pooling_2d.py
+++ b/tests/chainer_tests/functions_tests/pooling_tests/test_average_pooling_2d.py
@@ -51,17 +51,9 @@ def test_forward_gpu_no_cudnn(self):
         self.check_forward(cuda.to_gpu(self.x), False)
 
     def check_backward(self, x_data, y_grad, use_cudnn=True):
-        x = chainer.Variable(x_data)
-        y = functions.average_pooling_2d(x, 3, stride=2,
-                                         pad=1, use_cudnn=use_cudnn)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,), eps=1e-2)
-
-        gradient_check.assert_allclose(cuda.to_cpu(gx), cuda.to_cpu(x.grad))
+        gradient_check.check_backward(
+            functions.AveragePooling2D(3, 2, 1, False, use_cudnn),
+            x_data, y_grad, eps=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/pooling_tests/test_max_pooling_2d.py b/tests/chainer_tests/functions_tests/pooling_tests/test_max_pooling_2d.py
--- a/tests/chainer_tests/functions_tests/pooling_tests/test_max_pooling_2d.py
+++ b/tests/chainer_tests/functions_tests/pooling_tests/test_max_pooling_2d.py
@@ -72,18 +72,11 @@ def test_forward_gpu_no_cudnn(self):
         self.check_forward(cuda.to_gpu(self.x), False)
 
     def check_backward(self, x_data, y_grad, use_cudnn=True):
-        x = chainer.Variable(x_data)
-        y = functions.max_pooling_2d(x, 3, stride=2, pad=1,
-                                     cover_all=self.cover_all,
-                                     use_cudnn=use_cudnn)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(cuda.to_cpu(gx), cuda.to_cpu(x.grad))
+        gradient_check.check_backward(
+            functions.MaxPooling2D(
+                3, stride=2, pad=1, cover_all=self.cover_all,
+                use_cudnn=use_cudnn),
+            x_data, y_grad)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/functions_tests/pooling_tests/test_spatial_pyramid_pooling_2d.py b/tests/chainer_tests/functions_tests/pooling_tests/test_spatial_pyramid_pooling_2d.py
--- a/tests/chainer_tests/functions_tests/pooling_tests/test_spatial_pyramid_pooling_2d.py
+++ b/tests/chainer_tests/functions_tests/pooling_tests/test_spatial_pyramid_pooling_2d.py
@@ -72,20 +72,11 @@ def test_forward_gpu_no_cudnn(self):
         self.check_forward_ones(cuda.to_gpu(self.one), False)
 
     def check_backward(self, x_data, y_grad, use_cudnn=True):
-        x = chainer.Variable(x_data)
-        y = functions.spatial_pyramid_pooling_2d(
-            x, self.pyramid_height, self.pooling_class, use_cudnn=use_cudnn)
-        y.grad = y_grad
-        y.backward()
-
-        func = y.creator
-        f = lambda: func.forward((x.data,))
-        gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
-
-        gradient_check.assert_allclose(
-            cuda.to_cpu(gx),
-            cuda.to_cpu(x.grad),
-            atol=1e-04)
+        gradient_check.check_backward(
+            functions.SpatialPyramidPooling2D(
+                x_data.shape[1:], self.pyramid_height, self.pooling_class,
+                use_cudnn=use_cudnn),
+            x_data, y_grad, atol=1e-4)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/links_tests/activation_tests/test_maxout.py b/tests/chainer_tests/links_tests/activation_tests/test_maxout.py
--- a/tests/chainer_tests/links_tests/activation_tests/test_maxout.py
+++ b/tests/chainer_tests/links_tests/activation_tests/test_maxout.py
@@ -92,25 +92,13 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = self.link(x)
-        y.grad = y_grad
-        y.backward()
-
-        f = lambda: (self.link(x).data, )
         if self.initial_bias is None:
-            gx, gW = gradient_check.numerical_grad(
-                f, (x.data, self.link.W.data),
-                (y.grad, ), eps=1e-4)
+            params = (self.link.W,)
         else:
-            gx, gW, gb = gradient_check.numerical_grad(
-                f, (x.data, self.link.W.data, self.link.b.data),
-                (y.grad, ), eps=1e-4)
-
-        gradient_check.assert_allclose(gx, x.grad, atol=1e-2)
-        gradient_check.assert_allclose(gW, self.link.W.grad, atol=1e-2)
-        if self.initial_bias is not None:
-            gradient_check.assert_allclose(gb, self.link.b.grad, atol=1e-2)
+            params = (self.link.W, self.link.b)
+
+        gradient_check.check_backward(
+            self.link, x_data, y_grad, params, eps=1e-4, atol=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/links_tests/activation_tests/test_prelu.py b/tests/chainer_tests/links_tests/activation_tests/test_prelu.py
--- a/tests/chainer_tests/links_tests/activation_tests/test_prelu.py
+++ b/tests/chainer_tests/links_tests/activation_tests/test_prelu.py
@@ -51,18 +51,8 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = self.link(x)
-        y.grad = y_grad
-        y.backward()
-
-        W = self.link.W
-        link = self.link
-        f = lambda: (link(x).data,)
-        gx, gW = gradient_check.numerical_grad(f, (x.data, W.data), (y.grad,))
-
-        gradient_check.assert_allclose(gx, x.grad)
-        gradient_check.assert_allclose(gW, W.grad, atol=1e-4)
+        gradient_check.check_backward(
+            self.link, x_data, y_grad, self.link.W, atol=1e-4)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/links_tests/connection_tests/test_bilinear.py b/tests/chainer_tests/links_tests/connection_tests/test_bilinear.py
--- a/tests/chainer_tests/links_tests/connection_tests/test_bilinear.py
+++ b/tests/chainer_tests/links_tests/connection_tests/test_bilinear.py
@@ -20,26 +20,12 @@ def _check_forward(e1, e2, f, y_expect):
 
 
 def _check_backward(e1, e2, y_grad, link, bias):
-    e1 = chainer.Variable(e1)
-    e2 = chainer.Variable(e2)
-    y = link(e1, e2)
-    y.grad = y_grad
-    y.backward()
-    f = lambda: (link(e1, e2).data,)
-
-    ge1, ge2, gW = gradient_check.numerical_grad(
-        f, (e1.data, e2.data, link.W.data), (y.grad,), eps=1e-2)
-    gradient_check.assert_allclose(ge1, e1.grad, rtol=1e-3)
-    gradient_check.assert_allclose(ge2, e2.grad, rtol=1e-3)
-    gradient_check.assert_allclose(gW, link.W.grad, rtol=1e-3)
-
+    params = [link.W]
     if bias:
-        gV1, gV2, gb = gradient_check.numerical_grad(
-            f, (link.V1.data, link.V2.data, link.b.data),
-            (y.grad,), eps=1e-2)
-        gradient_check.assert_allclose(gV1, link.V1.grad, rtol=1e-3)
-        gradient_check.assert_allclose(gV2, link.V2.grad, rtol=1e-3)
-        gradient_check.assert_allclose(gb, link.b.grad, rtol=1e-3)
+        params.append(link.b)
+
+    gradient_check.check_backward(
+        link, (e1, e2), y_grad, params, eps=1e-2, rtol=1e-3)
 
 
 def _batch_to_gpu(*xs):
diff --git a/tests/chainer_tests/links_tests/connection_tests/test_convolution_2d.py b/tests/chainer_tests/links_tests/connection_tests/test_convolution_2d.py
--- a/tests/chainer_tests/links_tests/connection_tests/test_convolution_2d.py
+++ b/tests/chainer_tests/links_tests/connection_tests/test_convolution_2d.py
@@ -64,19 +64,8 @@ def test_forward_consistency_im2col(self):
         self.check_forward_consistency()
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = self.link(x)
-        y.grad = y_grad
-        y.backward()
-
-        f = lambda: (self.link(x).data,)
-        gx, gW, gb = gradient_check.numerical_grad(
-            f, (x.data, self.link.W.data, self.link.b.data), (y.grad,),
-            eps=1e-2)
-
-        gradient_check.assert_allclose(gx, x.grad)
-        gradient_check.assert_allclose(gW, self.link.W.grad)
-        gradient_check.assert_allclose(gb, self.link.b.grad)
+        gradient_check.check_backward(
+            self.link, x_data, y_grad, (self.link.W, self.link.b), eps=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/links_tests/connection_tests/test_deconvolution_2d.py b/tests/chainer_tests/links_tests/connection_tests/test_deconvolution_2d.py
--- a/tests/chainer_tests/links_tests/connection_tests/test_deconvolution_2d.py
+++ b/tests/chainer_tests/links_tests/connection_tests/test_deconvolution_2d.py
@@ -73,22 +73,12 @@ def test_forward_consistency(self):
         self.check_forward_consistency()
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = self.link(x)
-        y.grad = y_grad
-        y.backward()
-
-        f = lambda: (self.link(x).data,)
-        gx, gW = gradient_check.numerical_grad(
-            f, (x.data, self.link.W.data), (y.grad,), eps=1e-2)
+        params = [self.link.W]
         if not self.nobias:
-            gb, = gradient_check.numerical_grad(
-                f, (self.link.b.data,), (y.grad,), eps=1e-2)
+            params.append(self.link.b)
 
-        gradient_check.assert_allclose(gx, x.grad)
-        gradient_check.assert_allclose(gW, self.link.W.grad)
-        if not self.nobias:
-            gradient_check.assert_allclose(gb, self.link.b.grad)
+        gradient_check.check_backward(
+            self.link, x_data, y_grad, params, eps=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/links_tests/connection_tests/test_embed_id.py b/tests/chainer_tests/links_tests/connection_tests/test_embed_id.py
--- a/tests/chainer_tests/links_tests/connection_tests/test_embed_id.py
+++ b/tests/chainer_tests/links_tests/connection_tests/test_embed_id.py
@@ -48,14 +48,8 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = self.link(x)
-        y.grad = y_grad
-        y.backward()
-
-        f = lambda: (self.link(x).data,)
-        gW, = gradient_check.numerical_grad(f, (self.link.W.data,), (y.grad,))
-        gradient_check.assert_allclose(gW, self.link.W.grad)
+        gradient_check.check_backward(
+            self.link, x_data, y_grad, self.link.W)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/links_tests/connection_tests/test_gru.py b/tests/chainer_tests/links_tests/connection_tests/test_gru.py
--- a/tests/chainer_tests/links_tests/connection_tests/test_gru.py
+++ b/tests/chainer_tests/links_tests/connection_tests/test_gru.py
@@ -93,7 +93,8 @@ def check_backward(self, h_data, x_data, y_grad):
         y.grad = y_grad
         y.backward()
 
-        f = lambda: (_gru(self.link, h_data, x_data),)
+        def f():
+            return _gru(self.link, h_data, x_data),
         gx, = gradient_check.numerical_grad(f, (x.data,), (y.grad,))
         gradient_check.assert_allclose(gx, x.grad, atol=1e-3)
 
diff --git a/tests/chainer_tests/links_tests/connection_tests/test_linear.py b/tests/chainer_tests/links_tests/connection_tests/test_linear.py
--- a/tests/chainer_tests/links_tests/connection_tests/test_linear.py
+++ b/tests/chainer_tests/links_tests/connection_tests/test_linear.py
@@ -52,19 +52,8 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = self.link(x)
-        y.grad = y_grad
-        y.backward()
-
-        f = lambda: (self.link(x).data,)
-        gx, gW, gb = gradient_check.numerical_grad(
-            f, (x.data, self.link.W.data, self.link.b.data), (y.grad,),
-            eps=1e-2)
-
-        gradient_check.assert_allclose(gx, x.grad)
-        gradient_check.assert_allclose(gW, self.link.W.grad)
-        gradient_check.assert_allclose(gb, self.link.b.grad)
+        gradient_check.check_backward(
+            self.link, x_data, y_grad, (self.link.W, self.link.b), eps=1e-2)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/links_tests/loss_tests/test_hierarchical_softmax.py b/tests/chainer_tests/links_tests/loss_tests/test_hierarchical_softmax.py
--- a/tests/chainer_tests/links_tests/loss_tests/test_hierarchical_softmax.py
+++ b/tests/chainer_tests/links_tests/loss_tests/test_hierarchical_softmax.py
@@ -80,18 +80,9 @@ def test_forward(self):
             cpu_loss, cuda.to_cpu(gpu_loss))
 
     def check_backward(self, x_data, t_data, y_grad):
-        x = chainer.Variable(x_data)
-        t = chainer.Variable(t_data)
-        y = self.link(x, t)
-        y.grad = y_grad
-        y.backward()
-
-        f = lambda: (self.link(x, t).data,)
-        gx, _, gW = gradient_check.numerical_grad(
-            f, (x.data, t.data, self.link.W.data), (y.grad,), eps=1e-2)
-
-        gradient_check.assert_allclose(gx, x.grad, atol=1e-4)
-        gradient_check.assert_allclose(gW, self.link.W.grad, atol=1e-4)
+        gradient_check.check_backward(
+            self.link, (x_data, t_data), y_grad, self.link.W,
+            eps=1e-2, atol=1e-4)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/links_tests/loss_tests/test_negative_sampling.py b/tests/chainer_tests/links_tests/loss_tests/test_negative_sampling.py
--- a/tests/chainer_tests/links_tests/loss_tests/test_negative_sampling.py
+++ b/tests/chainer_tests/links_tests/loss_tests/test_negative_sampling.py
@@ -31,7 +31,9 @@ def check_backward(self, x_data, t_data, y_grad, use_cudnn=True):
 
         # fix samples
         negative_sampling.NegativeSamplingFunction.samples = y.creator.samples
-        f = lambda: (self.link(x, t).data,)
+
+        def f():
+            return (self.link(x, t).data,)
         gx, gW = gradient_check.numerical_grad(
             f, (x.data, W.data), (y.grad,), eps=1e-2)
         del negative_sampling.NegativeSamplingFunction.samples  # clean up
diff --git a/tests/chainer_tests/links_tests/normalization_tests/test_batch_normalization.py b/tests/chainer_tests/links_tests/normalization_tests/test_batch_normalization.py
--- a/tests/chainer_tests/links_tests/normalization_tests/test_batch_normalization.py
+++ b/tests/chainer_tests/links_tests/normalization_tests/test_batch_normalization.py
@@ -37,19 +37,9 @@ def test_forward_gpu(self):
         self.check_forward(cuda.to_gpu(self.x))
 
     def check_backward(self, x_data, y_grad):
-        x = chainer.Variable(x_data)
-        y = self.link(x)
-        y.grad = y_grad
-        y.backward()
-
-        f = lambda: (self.link(x).data,)
-        gx, ggamma, gbeta = gradient_check.numerical_grad(
-            f, (x.data, self.link.gamma.data, self.link.beta.data),
-            (y.grad,), eps=1e-2)
-
-        gradient_check.assert_allclose(gx, x.grad, rtol=1e-3, atol=1e-4)
-        gradient_check.assert_allclose(ggamma, self.link.gamma.grad)
-        gradient_check.assert_allclose(gbeta, self.link.beta.grad)
+        gradient_check.check_backward(
+            self.link, x_data, y_grad, (self.link.gamma, self.link.beta),
+            eps=1e-2, rtol=1e-3, atol=1e-4)
 
     @condition.retry(3)
     def test_backward_cpu(self):
diff --git a/tests/chainer_tests/test_gradient_check.py b/tests/chainer_tests/test_gradient_check.py
--- a/tests/chainer_tests/test_gradient_check.py
+++ b/tests/chainer_tests/test_gradient_check.py
@@ -49,7 +49,7 @@ def check_numerical_grad_one(self, f, df, xs, gys, eps):
         # matrix-vector multiplication of dfxs and dys
         dx_expect = tuple(map(lambda dfx: _dot(dfx, gys), dfxs))
 
-        func = lambda: f(xs)
+        def func(): return f(xs)
         dx_actual = gradient_check.numerical_grad(func, xs, gys, eps)
 
         print('eps: {}'.format(eps))
@@ -84,8 +84,9 @@ def test_numerical_grad_gpu(self):
 
 class NumericalGradientTest2(NumericalGradientTest):
 
-    f = lambda self, xs: (1,)
-    df = lambda self, xs: ((0,),)
+    def f(self, xs): return (1,)
+
+    def df(self, xs): return ((0,),)
 
 
 class NumericalGradientTest3(NumericalGradientTest):
@@ -159,7 +160,7 @@ def setUp(self):
     def check_reference(self, x):
         # A returned value and an input refers the same memory.
         # See issue #488
-        func = lambda: (x,)
+        def func(): return (x,)
         gx, = gradient_check.numerical_grad(func, (x,), (1,))
         gradient_check.assert_allclose(cuda.to_cpu(gx), 1)
 
diff --git a/tests/chainer_tests/utils_tests/test_type_check.py b/tests/chainer_tests/utils_tests/test_type_check.py
--- a/tests/chainer_tests/utils_tests/test_type_check.py
+++ b/tests/chainer_tests/utils_tests/test_type_check.py
@@ -110,7 +110,8 @@ class TestBinaryOperator(unittest.TestCase):
     def setUp(self):
         x = T.Variable(1, 'x')
         y = T.Variable(1, 'y')
-        f = lambda x, y: (x, y)
+
+        def f(x, y): return (x, y)
         self.op1 = T.BinaryOperator(7, x, y, '+', f)
         self.op2 = T.BinaryOperator(8, x, y, '+', f)
         self.op3 = T.BinaryOperator(9, x, y, '+', f)
@@ -136,7 +137,8 @@ class TestUnaryOperator(unittest.TestCase):
 
     def setUp(self):
         x = T.Variable(1, 'x')
-        f = lambda x: (x,)
+
+        def f(x): return (x,)
         self.op1 = T.UnaryOperator(8, x, '-', f)
         self.op2 = T.UnaryOperator(9, x, '-', f)
 
@@ -273,7 +275,8 @@ def setUp(self):
         x = T.Variable(1, 'x')
         y = T.Variable(1, 'y')
         z = T.Variable(2, 'z')
-        f = lambda x, y: x == y
+
+        def f(x, y): return x == y
         self.op1 = T.BoolBinaryOperator(x, y, '==', '!=', f)
         self.op2 = T.BoolBinaryOperator(x, z, '==', '!=', f)
 
diff --git a/tests/cupy_tests/core_tests/test_ndarray_get.py b/tests/cupy_tests/core_tests/test_ndarray_get.py
--- a/tests/cupy_tests/core_tests/test_ndarray_get.py
+++ b/tests/cupy_tests/core_tests/test_ndarray_get.py
@@ -22,24 +22,24 @@ def check_get(self, f, stream):
 
     @testing.for_all_dtypes()
     def test_contiguous_array(self, dtype):
-        contiguous_array = lambda xp: testing.shaped_arange(
-            (3,), xp=xp, dtype=dtype)
+        def contiguous_array(xp):
+            return testing.shaped_arange((3,), xp=xp, dtype=dtype)
         self.check_get(contiguous_array, None)
 
     @testing.for_all_dtypes()
     def test_non_contiguous_array(self, dtype):
-        non_contiguous_array = lambda xp: testing.shaped_arange(
-            (3,), xp=xp, dtype=dtype)[0::2]
+        def non_contiguous_array(xp):
+            return testing.shaped_arange((3,), xp=xp, dtype=dtype)[0::2]
         self.check_get(non_contiguous_array, None)
 
     @testing.for_all_dtypes()
     def test_contiguous_array_stream(self, dtype):
-        contiguous_array = lambda xp: testing.shaped_arange(
-            (3,), xp=xp, dtype=dtype)
+        def contiguous_array(xp):
+            return testing.shaped_arange((3,), xp=xp, dtype=dtype)
         self.check_get(contiguous_array, self.stream.ptr)
 
     @testing.for_all_dtypes()
     def test_non_contiguous_array_stream(self, dtype):
-        non_contiguous_array = lambda xp: testing.shaped_arange(
-            (3,), xp=xp, dtype=dtype)[0::2]
+        def non_contiguous_array(xp):
+            return testing.shaped_arange((3,), xp=xp, dtype=dtype)[0::2]
         self.check_get(non_contiguous_array, self.stream.ptr)