diff --git a/app/code/Magento/SampleData/Console/Command/SampleDataDeployCommand.php b/app/code/Magento/SampleData/Console/Command/SampleDataDeployCommand.php
index 158c588d113582756a03114fee0fbd24737ee0ff..88df47283133a2ceacf371b0d65cf730da1f346e 100644
--- a/app/code/Magento/SampleData/Console/Command/SampleDataDeployCommand.php
+++ b/app/code/Magento/SampleData/Console/Command/SampleDataDeployCommand.php
@@ -12,6 +12,7 @@ use Magento\Setup\Model\PackagesAuth;
 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\ArrayInput;
 use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 
 /**
@@ -19,6 +20,8 @@ use Symfony\Component\Console\Output\OutputInterface;
  */
 class SampleDataDeployCommand extends Command
 {
+    const OPTION_NO_UPDATE = 'no-update';
+
     /**
      * @var \Magento\Framework\Filesystem
      */
@@ -66,6 +69,12 @@ class SampleDataDeployCommand extends Command
     {
         $this->setName('sampledata:deploy')
             ->setDescription('Deploy sample data modules');
+        $this->addOption(
+            self::OPTION_NO_UPDATE,
+            null,
+            InputOption::VALUE_NONE,
+            'Update composer.json without executing composer update'
+        );
         parent::configure();
     }
 
@@ -80,6 +89,9 @@ class SampleDataDeployCommand extends Command
         if (!empty($sampleDataPackages)) {
             $baseDir = $this->filesystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath();
             $commonArgs = ['--working-dir' => $baseDir, '--no-progress' => 1];
+            if ($input->getOption(self::OPTION_NO_UPDATE)) {
+                $commonArgs['--no-update'] = 1;
+            }
             $packages = [];
             foreach ($sampleDataPackages as $name => $version) {
                 $packages[] = "$name:$version";
diff --git a/app/code/Magento/SampleData/Console/Command/SampleDataRemoveCommand.php b/app/code/Magento/SampleData/Console/Command/SampleDataRemoveCommand.php
index 36f5c591bedc34e80ff895d02b9b869fd3f744f3..5e10b6c6e59302aad9c0994cbe88000d81547692 100644
--- a/app/code/Magento/SampleData/Console/Command/SampleDataRemoveCommand.php
+++ b/app/code/Magento/SampleData/Console/Command/SampleDataRemoveCommand.php
@@ -8,6 +8,7 @@ namespace Magento\SampleData\Console\Command;
 
 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Magento\SampleData\Model\Dependency;
 use Symfony\Component\Console\Input\ArrayInput;
@@ -22,6 +23,8 @@ use Composer\Console\ApplicationFactory;
  */
 class SampleDataRemoveCommand extends Command
 {
+    const OPTION_NO_UPDATE = 'no-update';
+
     /**
      * @var Filesystem
      */
@@ -69,6 +72,12 @@ class SampleDataRemoveCommand extends Command
     {
         $this->setName('sampledata:remove')
             ->setDescription('Remove all sample data packages from composer.json');
+        $this->addOption(
+            self::OPTION_NO_UPDATE,
+            null,
+            InputOption::VALUE_NONE,
+            'Update composer.json without executing composer update'
+        );
         parent::configure();
     }
 
@@ -81,6 +90,9 @@ class SampleDataRemoveCommand extends Command
         if (!empty($sampleDataPackages)) {
             $baseDir = $this->filesystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath();
             $commonArgs = ['--working-dir' => $baseDir, '--no-interaction' => 1, '--no-progress' => 1];
+            if ($input->getOption(self::OPTION_NO_UPDATE)) {
+                $commonArgs['--no-update'] = 1;
+            }
             $packages = array_keys($sampleDataPackages);
             $arguments = array_merge(['command' => 'remove', 'packages' => $packages], $commonArgs);
             $commandInput = new ArrayInput($arguments);
diff --git a/app/code/Magento/SampleData/Test/Unit/Console/Command/AbstractSampleDataCommandTest.php b/app/code/Magento/SampleData/Test/Unit/Console/Command/AbstractSampleDataCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..090bb4256f80723cf95a2bf3ffa31f3d76372ec9
--- /dev/null
+++ b/app/code/Magento/SampleData/Test/Unit/Console/Command/AbstractSampleDataCommandTest.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SampleData\Test\Unit\Console\Command;
+
+use Composer\Console\Application;
+use Composer\Console\ApplicationFactory;
+use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Filesystem;
+use Magento\Framework\Filesystem\Directory\ReadInterface;
+use Magento\Framework\Filesystem\Directory\WriteInterface;
+use Magento\SampleData\Model\Dependency;
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\ArrayInputFactory;
+
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+abstract class AbstractSampleDataCommandTest extends TestCase
+{
+    /**
+     * @var ReadInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $directoryReadMock;
+
+    /**
+     * @var WriteInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $directoryWriteMock;
+
+    /**
+     * @var Filesystem|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filesystemMock;
+
+    /**
+     * @var Dependency|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $sampleDataDependencyMock;
+
+    /**
+     * @var ArrayInputFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $arrayInputFactoryMock;
+
+    /**
+     * @var Application|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $applicationMock;
+
+    /**
+     * @var ApplicationFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $applicationFactoryMock;
+
+    /**
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->directoryReadMock = $this->createMock(ReadInterface::class);
+        $this->directoryWriteMock = $this->createMock(WriteInterface::class);
+        $this->filesystemMock = $this->createMock(Filesystem::class);
+        $this->sampleDataDependencyMock = $this->createMock(Dependency::class);
+        $this->arrayInputFactoryMock = $this->createMock(ArrayInputFactory::class);
+        $this->applicationMock = $this->createMock(Application::class);
+        $this->applicationFactoryMock = $this->createPartialMock(ApplicationFactory::class, ['create']);
+    }
+
+    /**
+     * @param array $sampleDataPackages     Array in form [package_name => version_constraint]
+     * @param string $pathToComposerJson    Fake path to composer.json
+     * @param int $appRunResult             Composer exit code
+     * @param array $additionalComposerArgs Additional arguments that composer expects
+     */
+    protected function setupMocks(
+        $sampleDataPackages,
+        $pathToComposerJson,
+        $appRunResult,
+        $additionalComposerArgs = []
+    ) {
+        $this->directoryReadMock->expects($this->any())->method('getAbsolutePath')->willReturn($pathToComposerJson);
+        $this->filesystemMock->expects($this->any())->method('getDirectoryRead')->with(DirectoryList::ROOT)->willReturn(
+            $this->directoryReadMock
+        );
+        $this->sampleDataDependencyMock->expects($this->any())->method('getSampleDataPackages')->willReturn(
+            $sampleDataPackages
+        );
+        $this->arrayInputFactoryMock->expects($this->never())->method('create');
+
+        $this->applicationMock->expects($this->any())
+            ->method('run')
+            ->with(
+                new ArrayInput(
+                    array_merge(
+                        $this->expectedComposerArguments(
+                            $sampleDataPackages,
+                            $pathToComposerJson
+                        ),
+                        $additionalComposerArgs
+                    )
+                ),
+                $this->anything()
+            )
+            ->willReturn($appRunResult);
+
+        if (($appRunResult !== 0) && !empty($sampleDataPackages)) {
+            $this->applicationMock->expects($this->once())->method('resetComposer')->willReturnSelf();
+        }
+
+        $this->applicationFactoryMock->expects($this->any())
+            ->method('create')
+            ->willReturn($this->applicationMock);
+    }
+
+    /**
+     * Expected arguments for composer based on sample data packages and composer.json path
+     *
+     * @param array $sampleDataPackages
+     * @param string $pathToComposerJson
+     * @return array
+     */
+    abstract protected function expectedComposerArguments(
+        array $sampleDataPackages,
+        string $pathToComposerJson
+    ) : array;
+}
diff --git a/app/code/Magento/SampleData/Test/Unit/Console/Command/SampleDataDeployCommandTest.php b/app/code/Magento/SampleData/Test/Unit/Console/Command/SampleDataDeployCommandTest.php
index 464a6c9ccd832921c8e781225c306efa55ab6d5a..450b2d8798f52491bfd8976f609c343fda18037d 100644
--- a/app/code/Magento/SampleData/Test/Unit/Console/Command/SampleDataDeployCommandTest.php
+++ b/app/code/Magento/SampleData/Test/Unit/Console/Command/SampleDataDeployCommandTest.php
@@ -9,66 +9,26 @@ use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\SampleData\Console\Command\SampleDataDeployCommand;
 use Magento\Setup\Model\PackagesAuth;
 use Symfony\Component\Console\Tester\CommandTester;
-use Magento\Framework\Filesystem;
-use Magento\Framework\Filesystem\Directory\ReadInterface;
-use Magento\Framework\Filesystem\Directory\WriteInterface;
-use Magento\SampleData\Model\Dependency;
-use Symfony\Component\Console\Input\ArrayInputFactory;
-use Composer\Console\ApplicationFactory;
-use Composer\Console\Application;
 
-/**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
+class SampleDataDeployCommandTest extends AbstractSampleDataCommandTest
 {
     /**
-     * @var ReadInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $directoryReadMock;
-
-    /**
-     * @var WriteInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $directoryWriteMock;
-
-    /**
-     * @var Filesystem|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $filesystemMock;
-
-    /**
-     * @var Dependency|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $sampleDataDependencyMock;
-
-    /**
-     * @var ArrayInputFactory|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $arrayInputFactoryMock;
-
-    /**
-     * @var Application|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $applicationMock;
-
-    /**
-     * @var ApplicationFactory|\PHPUnit_Framework_MockObject_MockObject
+     * @param bool $authExist               True to test with existing auth.json, false without
      */
-    private $applicationFactoryMock;
-
-    /**
-     * @return void
-     */
-    protected function setUp()
+    protected function setupMocksForAuthFile($authExist)
     {
-        $this->directoryReadMock = $this->createMock(ReadInterface::class);
-        $this->directoryWriteMock = $this->createMock(WriteInterface::class);
-        $this->filesystemMock = $this->createMock(Filesystem::class);
-        $this->sampleDataDependencyMock = $this->createMock(Dependency::class);
-        $this->arrayInputFactoryMock = $this->createMock(ArrayInputFactory::class);
-        $this->applicationMock = $this->createMock(Application::class);
-        $this->applicationFactoryMock = $this->createPartialMock(ApplicationFactory::class, ['create']);
+        $this->directoryWriteMock->expects($this->once())
+            ->method('isExist')
+            ->with(PackagesAuth::PATH_TO_AUTH_FILE)
+            ->willReturn($authExist);
+        $this->directoryWriteMock->expects($authExist ? $this->never() : $this->once())->method('writeFile')->with(
+            PackagesAuth::PATH_TO_AUTH_FILE,
+            '{}'
+        );
+        $this->filesystemMock->expects($this->once())
+            ->method('getDirectoryWrite')
+            ->with(DirectoryList::COMPOSER_HOME)
+            ->willReturn($this->directoryWriteMock);
     }
 
     /**
@@ -82,68 +42,36 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
      */
     public function testExecute(array $sampleDataPackages, $appRunResult, $expectedMsg, $authExist)
     {
-        $pathToComposerJson = '/path/to/composer.json';
-
-        $this->directoryReadMock->expects($this->any())
-            ->method('getAbsolutePath')
-            ->willReturn($pathToComposerJson);
-        $this->directoryWriteMock->expects($this->once())
-            ->method('isExist')
-            ->with(PackagesAuth::PATH_TO_AUTH_FILE)
-            ->willReturn($authExist);
-        $this->directoryWriteMock->expects($authExist ? $this->never() : $this->once())
-            ->method('writeFile')
-            ->with(PackagesAuth::PATH_TO_AUTH_FILE, '{}');
-        $this->filesystemMock->expects($this->any())
-            ->method('getDirectoryRead')
-            ->with(DirectoryList::ROOT)
-            ->willReturn($this->directoryReadMock);
-        $this->filesystemMock->expects($this->once())
-            ->method('getDirectoryWrite')
-            ->with(DirectoryList::COMPOSER_HOME)
-            ->willReturn($this->directoryWriteMock);
-        $this->sampleDataDependencyMock->expects($this->any())
-            ->method('getSampleDataPackages')
-            ->willReturn($sampleDataPackages);
-        $this->arrayInputFactoryMock->expects($this->never())
-            ->method('create');
-
-        array_walk($sampleDataPackages, function (&$v, $k) {
-            $v = "$k:$v";
-        });
-
-        $packages = array_values($sampleDataPackages);
-
-        $requireArgs = [
-            'command'       => 'require',
-            '--working-dir' => $pathToComposerJson,
-            '--no-progress' => 1,
-            'packages'      => $packages,
-        ];
-        $commandInput = new \Symfony\Component\Console\Input\ArrayInput($requireArgs);
-
-        $this->applicationMock->expects($this->any())
-            ->method('run')
-            ->with($commandInput, $this->anything())
-            ->willReturn($appRunResult);
-
-        if (($appRunResult !== 0) && !empty($sampleDataPackages)) {
-            $this->applicationMock->expects($this->once())->method('resetComposer')->willReturnSelf();
-        }
+        $this->setupMocks($sampleDataPackages, '/path/to/composer.json', $appRunResult);
+        $this->setupMocksForAuthFile($authExist);
+        $commandTester = $this->createCommandTester();
+        $commandTester->execute([]);
 
-        $this->applicationFactoryMock->expects($this->any())
-            ->method('create')
-            ->willReturn($this->applicationMock);
+        $this->assertEquals($expectedMsg, $commandTester->getDisplay());
+    }
 
-        $commandTester = new CommandTester(
-            new SampleDataDeployCommand(
-                $this->filesystemMock,
-                $this->sampleDataDependencyMock,
-                $this->arrayInputFactoryMock,
-                $this->applicationFactoryMock
-            )
+    /**
+     * @param array     $sampleDataPackages
+     * @param int       $appRunResult - int 0 if everything went fine, or an error code
+     * @param string    $expectedMsg
+     * @param bool      $authExist
+     * @return          void
+     *
+     * @dataProvider processDataProvider
+     */
+    public function testExecuteWithNoUpdate(array $sampleDataPackages, $appRunResult, $expectedMsg, $authExist)
+    {
+        $this->setupMocks(
+            $sampleDataPackages,
+            '/path/to/composer.json',
+            $appRunResult,
+            ['--no-update' => 1]
         );
-        $commandTester->execute([]);
+        $this->setupMocksForAuthFile($authExist);
+        $commandInput = ['--no-update' => 1];
+
+        $commandTester = $this->createCommandTester();
+        $commandTester->execute($commandInput);
 
         $this->assertEquals($expectedMsg, $commandTester->getDisplay());
     }
@@ -154,13 +82,13 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
     public function processDataProvider()
     {
         return [
-            [
+            'No sample data found' => [
                 'sampleDataPackages' => [],
                 'appRunResult' => 1,
                 'expectedMsg' => 'There is no sample data for current set of modules.' . PHP_EOL,
                 'authExist' => true,
             ],
-            [
+            'No auth.json found' => [
                 'sampleDataPackages' => [
                     'magento/module-cms-sample-data' => '1.0.0-beta',
                 ],
@@ -169,7 +97,7 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
                     . PHP_EOL,
                 'authExist' => false,
             ],
-            [
+            'Successful sample data installation' => [
                 'sampleDataPackages' => [
                     'magento/module-cms-sample-data' => '1.0.0-beta',
                 ],
@@ -204,6 +132,14 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
             ->with(DirectoryList::COMPOSER_HOME)
             ->willReturn($this->directoryWriteMock);
 
+        $this->createCommandTester()->execute([]);
+    }
+
+    /**
+     * @return CommandTester
+     */
+    private function createCommandTester(): CommandTester
+    {
         $commandTester = new CommandTester(
             new SampleDataDeployCommand(
                 $this->filesystemMock,
@@ -212,6 +148,36 @@ class SampleDataDeployCommandTest extends \PHPUnit\Framework\TestCase
                 $this->applicationFactoryMock
             )
         );
-        $commandTester->execute([]);
+        return $commandTester;
+    }
+
+    /**
+     * @param $sampleDataPackages
+     * @param $pathToComposerJson
+     * @return array
+     */
+    protected function expectedComposerArguments(
+        array $sampleDataPackages,
+        string $pathToComposerJson
+    ) : array {
+        return [
+            'command' => 'require',
+            '--working-dir' => $pathToComposerJson,
+            '--no-progress' => 1,
+            'packages' => $this->packageVersionStrings($sampleDataPackages),
+        ];
+    }
+
+    /**
+     * @param array $sampleDataPackages
+     * @return array
+     */
+    private function packageVersionStrings(array $sampleDataPackages): array
+    {
+        array_walk($sampleDataPackages, function (&$v, $k) {
+            $v = "$k:$v";
+        });
+
+        return array_values($sampleDataPackages);
     }
 }
diff --git a/app/code/Magento/SampleData/Test/Unit/Console/Command/SampleDataRemoveCommandTest.php b/app/code/Magento/SampleData/Test/Unit/Console/Command/SampleDataRemoveCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7fce70fd9c3764acaf37c6106519d2e10add7832
--- /dev/null
+++ b/app/code/Magento/SampleData/Test/Unit/Console/Command/SampleDataRemoveCommandTest.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SampleData\Test\Unit\Console\Command;
+
+use Magento\SampleData\Console\Command\SampleDataRemoveCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class SampleDataRemoveCommandTest extends AbstractSampleDataCommandTest
+{
+
+    /**
+     * @param array     $sampleDataPackages
+     * @param int       $appRunResult - int 0 if everything went fine, or an error code
+     * @param string    $expectedMsg
+     * @return          void
+     *
+     * @dataProvider processDataProvider
+     */
+    public function testExecute(array $sampleDataPackages, $appRunResult, $expectedMsg)
+    {
+        $this->setupMocks($sampleDataPackages, '/path/to/composer.json', $appRunResult);
+        $commandTester = $this->createCommandTester();
+        $commandTester->execute([]);
+
+        $this->assertEquals($expectedMsg, $commandTester->getDisplay());
+    }
+
+    /**
+     * @param array     $sampleDataPackages
+     * @param int       $appRunResult - int 0 if everything went fine, or an error code
+     * @param string    $expectedMsg
+     * @return          void
+     *
+     * @dataProvider processDataProvider
+     */
+    public function testExecuteWithNoUpdate(array $sampleDataPackages, $appRunResult, $expectedMsg)
+    {
+        $this->setupMocks(
+            $sampleDataPackages,
+            '/path/to/composer.json',
+            $appRunResult,
+            ['--no-update' => 1]
+        );
+        $commandInput = ['--no-update' => 1];
+
+        $commandTester = $this->createCommandTester();
+        $commandTester->execute($commandInput);
+
+        $this->assertEquals($expectedMsg, $commandTester->getDisplay());
+    }
+
+    /**
+     * @return array
+     */
+    public function processDataProvider()
+    {
+        return [
+            'No sample data found' => [
+                'sampleDataPackages' => [],
+                'appRunResult' => 1,
+                'expectedMsg' => 'There is no sample data for current set of modules.' . PHP_EOL,
+            ],
+            'Successful sample data installation' => [
+                'sampleDataPackages' => [
+                    'magento/module-cms-sample-data' => '1.0.0-beta',
+                ],
+                'appRunResult' => 0,
+                'expectedMsg' => '',
+            ],
+        ];
+    }
+
+    /**
+     * @return CommandTester
+     */
+    private function createCommandTester(): CommandTester
+    {
+        $commandTester = new CommandTester(
+            new SampleDataRemoveCommand(
+                $this->filesystemMock,
+                $this->sampleDataDependencyMock,
+                $this->arrayInputFactoryMock,
+                $this->applicationFactoryMock
+            )
+        );
+        return $commandTester;
+    }
+
+    /**
+     * @param $sampleDataPackages
+     * @param $pathToComposerJson
+     * @return array
+     */
+    protected function expectedComposerArguments(
+        array $sampleDataPackages,
+        string $pathToComposerJson
+    ) : array {
+        return [
+            'command' => 'remove',
+            '--working-dir' => $pathToComposerJson,
+            '--no-interaction' => 1,
+            '--no-progress' => 1,
+            'packages' => array_keys($sampleDataPackages),
+        ];
+    }
+}